Example #1
0
        /// <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);
            }
        }
Example #2
0
        /// <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>
        /// enter the given sapience state
        /// </summary>
        /// <param name="stateDef">The state definition.</param>
        /// <param name="initialLevel">The initial level.</param>
        public void EnterState([NotNull] SapienceStateDef stateDef, float initialLevel)
        {
            _sapienceState?.Exit();
            _sapienceState = stateDef.CreateState();


            //need to refresh comps and needs for pawn here
            Pawn.needs?.AddOrRemoveNeedsAsAppropriate();
            _sapienceState.Init(this);
            SapienceLevel = FormerHumanUtilities.GetQuantizedSapienceLevel(initialLevel);
            PawnComponentsUtility.AddAndRemoveDynamicComponents(Pawn);
            var sNeed = SapienceNeed;

            sNeed?.SetSapience(initialLevel);
            _sapienceState.Enter();

            if (Pawn.Faction == Faction.OfPlayer)
            {
                Find.ColonistBar?.MarkColonistsDirty();
            }

            //initialize work settings if they have it
            Pawn.workSettings?.EnableAndInitializeIfNotAlreadyInitialized();

            //interrupts any jobs in case this changes their intelligence
            Pawn.jobs?.EndCurrentJob(JobCondition.InterruptForced);
        }
Example #4
0
        /// <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();
        }
Example #5
0
 /// <summary>
 /// Applies the post tf effects.
 /// this should be called just before the original pawn is cleaned up
 /// </summary>
 /// <param name="original">The original.</param>
 /// <param name="transformedPawn">The transformed pawn.</param>
 protected override void ApplyPostTfEffects(Pawn original, Pawn transformedPawn, TransformationRequest request)
 {
     //apply apparel damage
     ApplyApparelDamage(original, transformedPawn.def);
     FormerHumanUtilities.TryAssignBackstoryToTransformedPawn(transformedPawn, original);
     base.ApplyPostTfEffects(original, transformedPawn, request);
 }
Example #6
0
        private void MakeMergedPawn([NotNull] SapienceTracker sTracker)
        {
            if (sTracker.CurrentState != null)
            {
                return;
            }

            (Pawn p1, Pawn p2) = FormerHumanUtilities.GenerateRandomUnmergedHuman(sTracker.Pawn);

            CleanupPawn(p1);
            CleanupPawn(p2);
            Pawn[] tmpArr = { p1, p2 };
            MergedPawnUtilities.TransferToMergedPawn(tmpArr, sTracker.Pawn);

            var tfPawn = new MergedPawns()
            {
                meld      = sTracker.Pawn,
                originals = new List <Pawn> {
                    p1, p2
                }
            };

            var gComp = Find.World.GetComponent <PawnmorphGameComp>();

            gComp.AddTransformedPawn(tfPawn);

            //TODO figure out how relationships work for merged pawns

            sTracker.EnterState(SapienceStateDefOf.MergedPawn, Rand.Range(0.2f, 1));
        }
Example #7
0
        private float GetInteractionWeight(Pawn initiator, Pawn recipient, Filter <PawnRelationDef> relationRestriction,
                                           bool mustBeColonist)
        {
            Pawn oHuman = FormerHumanUtilities.GetOriginalPawnOfFormerHuman(recipient);

            if (relationRestriction != null) //check any relationships if applicable
            {
                if (oHuman == null)
                {
                    if (mustBeColonist)
                    {
                        return(0);                //if there is no original pawn they can't be a colonist
                    }
                    if (!relationRestriction.isBlackList)
                    {
                        return
                            (0); //if the filter is a white list a blank original pawn can't pass it because there is no relationship
                    }
                    return(BaseInteractionChance);
                }


                foreach (PawnRelationDef pawnRelationDef in initiator.GetRelations(oHuman))
                {
                    if (relationRestriction.PassesFilter(pawnRelationDef))
                    {
                        return(BaseInteractionChance);
                    }
                }

                return(0); //none passed
            }

            return(BaseInteractionChance);
        }
        /// <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);
            }
        }
Example #9
0
 static void InitializeForFormerHumans([NotNull] Pawn_WorkSettings __instance, [NotNull] Pawn ___pawn)
 {
     if (___pawn.IsSapientOrFeralFormerHuman())
     {
         FormerHumanUtilities.InitializeWorkSettingsFor(___pawn, __instance);
     }
 }
 static void InitializeForFormerHumans([NotNull] Pawn_WorkSettings __instance, [NotNull] Pawn ___pawn)
 {
     if (___pawn.IsFormerHuman() && ___pawn.workSettings != null)
     {
         FormerHumanUtilities.InitializeWorkSettingsFor(___pawn, __instance);
     }
 }
 /// <summary>
 /// called before the mental state is started
 /// </summary>
 public override void PreStart()
 {
     _prey = FormerHumanUtilities.FindRandomPreyFor(pawn);
     if (_prey == null)
     {
         Log.Error($"could not find prey for {pawn.Name}");
     }
 }
Example #12
0
        private void MakePawnPermanentlyFeral(Pawn obj)
        {
            if (obj?.IsFormerHuman() != true)
            {
                return;
            }

            FormerHumanUtilities.MakePermanentlyFeral(obj);
        }
        /// <summary>
        ///     Makes the parent a former human.
        /// </summary>
        /// <returns></returns>
        public void MakeFormerHuman(float initialLevel) //TODO move most of FormerHumanUtilities.MakeAnimalSapient here
        {
            if (_isFormerHuman)
            {
                Log.Warning($"{nameof(MakeFormerHuman)} is being called on {parent.def}'s {nameof(FormerHumanTracker)} more then once!");
                return;
            }

            _isFormerHuman = true;
            SapienceLevel  = FormerHumanUtilities.GetQuantizedSapienceLevel(initialLevel);
        }
        /// <summary>
        ///     Tries to revert the transformed pawn instance, implementation.
        /// </summary>
        /// <param name="transformedPawn">The transformed pawn.</param>
        /// <returns></returns>
        protected override bool TryRevertImpl(TransformedPawnSingle transformedPawn)
        {
            if (transformedPawn == null)
            {
                throw new ArgumentNullException(nameof(transformedPawn));
            }
            if (!transformedPawn.IsValid)
            {
                Log.Warning(nameof(SimpleMechaniteMutagen) + " received an invalid transformed pawn to revert");
                return(false);
            }


            Pawn animal = transformedPawn.animal;

            if (animal == null)
            {
                return(false);
            }
            var rFaction = transformedPawn.FactionResponsible;


            var spawned = (Pawn)GenSpawn.Spawn(transformedPawn.original, animal.PositionHeld, animal.MapHeld);

            if (spawned.Faction != animal.Faction && rFaction == null) //if the responsible faction is null (no one knows who did it) have the reverted pawn join that faction
            {
                spawned.SetFaction(animal.Faction);
            }


            for (var i = 0; i < 10; i++)
            {
                IntermittentMagicSprayer.ThrowMagicPuffDown(spawned.Position.ToVector3(), spawned.MapHeld);
                IntermittentMagicSprayer.ThrowMagicPuffUp(spawned.Position.ToVector3(), spawned.MapHeld);
            }

            //transfer hediffs from the former human back onto the original pawn
            FormerHumanUtilities.TransferHediffs(animal, spawned);

            SetHumanoidSapience(spawned, animal);

            FixBondRelationship(spawned, animal);
            FormerHumanUtilities.TransferEverything(animal, spawned);

            spawned.Faction?.Notify_MemberReverted(spawned, animal, spawned.Map == null, spawned.Map);

            ReactionsHelper.OnPawnReverted(spawned, animal, transformedPawn.reactionStatus);
            spawned.health.AddHediff(MorphTransformationDefOf.StabiliserHigh); //add stabilizer on reversion


            TransformerUtility.CleanUpHumanPawnPostTf(animal, null);
            animal.Destroy();
            return(true);
        }
        /// <summary>
        ///     Sets the sapience.
        /// </summary>
        /// <param name="sapience">The sapience.</param>
        public void SetSapience(float sapience)
        {
            _seekerLevel = Mathf.Clamp(sapience, 0, Mathf.Min(MaxLevel, Limit));
            CurLevel     = _seekerLevel;

            SapienceLevel cLevel = FormerHumanUtilities.GetQuantizedSapienceLevel(CurLevel);

            if (_currentLevel != cLevel)
            {
                _currentLevel = cLevel;
                OnSapienceLevelChanges();
            }
        }
Example #16
0
 /// <summary>
 ///     Exposes the data.
 /// </summary>
 public override void ExposeData()
 {
     base.ExposeData();
     Scribe_Values.Look(ref _seekerLevel, nameof(_seekerLevel), -1);
     if (Scribe.mode == LoadSaveMode.PostLoadInit)
     {
         if (_seekerLevel < 0)
         {
             _seekerLevel = CurLevel;
         }
         _currentLevel = FormerHumanUtilities.GetQuantizedSapienceLevel(_seekerLevel);
         CurLevel      = Mathf.Clamp(CurLevel, 0, MaxLevel);
     }
 }
        /// <summary>
        ///     Tries to revert the transformed pawn instance, implementation.
        /// </summary>
        /// <param name="transformedPawn">The transformed pawn.</param>
        /// <returns></returns>
        protected override bool TryRevertImpl(TransformedPawnSingle transformedPawn)
        {
            if (transformedPawn == null)
            {
                throw new ArgumentNullException(nameof(transformedPawn));
            }
            if (!transformedPawn.IsValid)
            {
                Log.Warning(nameof(SimpleMechaniteMutagen) + " received an invalid transformed pawn to revert");
                return(false);
            }


            Pawn animal = transformedPawn.animal;

            Hediff tfHumanHediff = animal?.health?.hediffSet?.GetFirstHediffOfDef(TfHediffDefOf.TransformedHuman);

            if (tfHumanHediff == null)
            {
                return(false);
            }
            var rFaction = transformedPawn.FactionResponsible;


            Log.Message($"going to spawn {transformedPawn.original.Name} {transformedPawn.original.KindLabel}");
            var spawned = (Pawn)GenSpawn.Spawn(transformedPawn.original, animal.PositionHeld, animal.MapHeld);

            if (spawned.Faction != animal.Faction && rFaction == null) //if the responsible faction is null (no one knows who did it) have the reverted pawn join that faction
            {
                spawned.SetFaction(animal.Faction);
            }


            for (var i = 0; i < 10; i++)
            {
                IntermittentMagicSprayer.ThrowMagicPuffDown(spawned.Position.ToVector3(), spawned.MapHeld);
                IntermittentMagicSprayer.ThrowMagicPuffUp(spawned.Position.ToVector3(), spawned.MapHeld);
            }

            FixBondRelationship(spawned, animal);
            FormerHumanUtilities.TransferEverything(animal, spawned);

            spawned.Faction?.Notify_MemberReverted(spawned, animal, spawned.Map == null, spawned.Map);

            ReactionsHelper.OnPawnReverted(spawned, animal, transformedPawn.reactionStatus);
            spawned.health.AddHediff(MorphTransformationDefOf.StabiliserHigh); //add stabilizer on reversion

            animal.Destroy();
            return(true);
        }
Example #18
0
        /// <summary>
        /// Generates the things that can be sold
        /// </summary>
        /// <param name="forTile">For tile.</param>
        /// <param name="forFaction">For faction.</param>
        /// <returns></returns>
        public override IEnumerable <Thing> GenerateThings(int forTile, Faction forFaction = null)
        {
            var enumer = GenerateThingEnumer(forTile, forFaction).ToList();

            foreach (Pawn pawn in enumer.OfType <Pawn>())
            {
                if (!pawn.IsFormerHuman())
                {
                    continue;
                }
                FormerHumanUtilities.NotifyRelatedPawnsFormerHuman(pawn, FormerHumanUtilities.RELATED_SOLD_FORMER_HUMAN_LETTER,
                                                                   FormerHumanUtilities.RELATED_SOLD_FORMER_HUMAN_LETTER_LABEL);
            }
            return(enumer);
        }
Example #19
0
        /// <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 IEnumerable <Toil> Postfix(IEnumerable <Toil> values, [NotNull] JobDriver_PredatorHunt __instance)
            {
                foreach (Toil toil in values)
                {
                    yield return(toil);
                }

                if (!__instance.pawn.IsSapientOrFeralFormerHuman())
                {
                    yield break;
                }
                yield return(Toils_General.Do(() =>
                {
                    FormerHumanUtilities.GiveSapientAnimalHuntingThought(__instance.pawn,
                                                                         __instance.Prey);
                }));
            }
        static void MakeAnimalSapientFormerHuman(Pawn pawn)
        {
            if (pawn == null)
            {
                return;
            }
            if (pawn.IsFormerHuman())
            {
                return;
            }
            if (!pawn.RaceProps.Animal)
            {
                return;
            }

            FormerHumanUtilities.MakeAnimalSapient(pawn);
        }
Example #22
0
        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));
        }
Example #23
0
        void TryStartRandomHunt(Pawn pawn)
        {
            if (!pawn.RaceProps.predator)
            {
                return;
            }
            var prey = FormerHumanUtilities.FindRandomPreyFor(pawn);

            if (prey == null)
            {
                return;
            }
            var job = new Job(JobDefOf.PredatorHunt, prey)
            {
                killIncappedTarget = true
            };

            pawn.jobs?.StartJob(job, JobCondition.InterruptForced);
        }
        /// <summary>Adds the hediff if not permanently feral.</summary>
        /// <param name="pawn">The pawn.</param>
        /// <param name="hediff">The hediff.</param>
        public static void AddHediffIfNotPermanentlyFeral(Pawn pawn, HediffDef hediff)
        {
            if (!pawn.health.hediffSet.HasHediff(HediffDef.Named("PermanentlyFeral")) && !pawn.health.hediffSet.HasHediff(hediff))
            // If a pawn does not have the PermanentlyFeral hediff nor the provided hediff...
            {
                Hediff xhediff = HediffMaker.MakeHediff(hediff, pawn);     // ...create an initialized version of the provided hediff...
                xhediff.Severity = Rand.Range(0.00f, 1.00f);               // ...set it to a random severity...
                pawn.health.AddHediff(xhediff);                            // ...then apply it..
                PawnComponentsUtility.AddAndRemoveDynamicComponents(pawn); //make sure they have all the dynamic comps they need

                //make sure it has a name
                if (pawn.Name == null)
                {
                    pawn.Name = new NameSingle(pawn.LabelShort);
                }

                FormerHumanUtilities.TryAssignBackstoryToTransformedPawn(pawn, null); //try to assign them a background if they're sapient
            }
        }
        /// <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();
                }
            }
        }
 /// <summary>
 ///     called every so often by the need manager.
 /// </summary>
 /// <exception cref="System.NotImplementedException"></exception>
 public override void NeedInterval()
 {
     base.NeedInterval();
     if (pawn.IsHashIntervalTick(TimeMetrics.TICKS_PER_REAL_SECOND)) //just every second or so
     {
         TrySubscribe();
         CalculateCachesIfNeeded();
         _seekerLevel = Mathf.Min(_seekerLevel, Limit);
         float instinctChange = GetInstinctChangePerTick(pawn) * TimeMetrics.TICKS_PER_REAL_SECOND;
         if (Mathf.Abs(instinctChange) > EPSILON)
         {
             AddInstinctChange(instinctChange);
         }
         //_maxLevelCached = null;
         SapienceLevel sLevel = FormerHumanUtilities.GetQuantizedSapienceLevel(CurLevel);
         if (sLevel != _currentLevel)
         {
             _currentLevel = sLevel;
             OnSapienceLevelChanges();
         }
     }
 }
Example #27
0
        /// <summary>
        ///     called every so often by the need manager.
        /// </summary>
        /// <exception cref="System.NotImplementedException"></exception>
        public override void NeedInterval()
        {
            base.NeedInterval();
            if (pawn.IsHashIntervalTick(TimeMetrics.TICKS_PER_REAL_SECOND)) //just every second or so
            {
                float instinctChange = GetInstinctChangePerTick(pawn) * TimeMetrics.TICKS_PER_REAL_SECOND;
                if (Mathf.Abs(instinctChange) > EPSILON)
                {
                    AddInstinctChange(Mathf.CeilToInt(instinctChange));
                }
                _maxLevelCached = null;
                SapienceLevel sLevel = FormerHumanUtilities.GetQuantizedSapienceLevel(CurLevel);
                if (sLevel != _currentLevel)
                {
                    _currentLevel = sLevel;
                    OnSapienceLevelChanges();
                }

                if (_currentLevel == SapienceLevel.Feral && Rand.MTBEventOccurs(4, 60000f, 30f))
                {
                    TriggerPermanentlyFeralChange();
                }
            }
        }
Example #28
0
        internal void MakePermanentlyFeral()
        {
            Hediff fHediff;

            if (StateDef.forcedHediff != null)
            {
                fHediff = Pawn.health.hediffSet.GetFirstHediffOfDef(StateDef.forcedHediff);
            }
            else
            {
                fHediff = null;
            }

            //transfer relationships back if possible
            var  gComp = Find.World.GetComponent <PawnmorphGameComp>();
            Pawn oPawn = gComp.GetTransformedPawnContaining(Pawn)?.Item1?.OriginalPawns.FirstOrDefault();

            if (oPawn == Pawn)
            {
                oPawn = null;
            }

            Pawn_RelationsTracker aRelations = Pawn.relations;

            if (aRelations != null && oPawn != null)
            {
                FormerHumanUtilities.TransferRelationsToOriginal(oPawn, Pawn);
            }

            Pawn.health.AddHediff(TfHediffDefOf.PermanentlyFeral);
            if (fHediff != null)
            {
                Pawn.health.RemoveHediff(fHediff);
            }

            var             loader     = Find.World.GetComponent <PawnmorphGameComp>();
            TransformedPawn inst       = loader.GetTransformedPawnContaining(Pawn)?.Item1;
            var             singleInst = inst as TransformedPawnSingle; //hacky, need to come up with a better solution

            foreach (Pawn instOriginalPawn in inst?.OriginalPawns ?? Enumerable.Empty <Pawn>()
                     ) //needed to handle merges correctly
            {
                ReactionsHelper.OnPawnPermFeral(instOriginalPawn, Pawn,
                                                singleInst?.reactionStatus ?? FormerHumanReactionStatus.Wild);
            }

            //remove the original and destroy the pawns
            foreach (Pawn instOriginalPawn in inst?.OriginalPawns ?? Enumerable.Empty <Pawn>())
            {
                instOriginalPawn.Destroy();
            }

            if (inst != null)
            {
                loader.RemoveInstance(inst);
            }

            if (inst != null || Pawn.Faction == Faction.OfPlayer)
            {
                Find.LetterStack.ReceiveLetter("LetterHediffFromPermanentTFLabel".Translate(Pawn.LabelShort).CapitalizeFirst(),
                                               "LetterHediffFromPermanentTF".Translate(Pawn.LabelShort).CapitalizeFirst(),
                                               LetterDefOf.NegativeEvent, Pawn);
            }

            Pawn.needs?.AddOrRemoveNeedsAsAppropriate(); //make sure any comps get added/removed as appropriate
            PawnComponentsUtility.AddAndRemoveDynamicComponents(Pawn);
        }
Example #29
0
        /// <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;

            faction = GetFaction(request, original);

            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.
            float sapienceLevel = request.forcedSapienceLevel ?? GetSapienceLevel(original, animalToSpawn);

            if (request.forcedFaction == null && original.Faction != faction && original.Faction != animalToSpawn.Faction && FormerHumanUtilities.GetQuantizedSapienceLevel(sapienceLevel) <= SapienceLevel.MostlySapient)
            {
                //set the faction to the original's if mostly sapient or above
                animalToSpawn.SetFaction(original.Faction);
            }


            GiveTransformedPawnSapienceState(animalToSpawn, sapienceLevel);

            FormerHumanUtilities.InitializeTransformedPawn(original, animalToSpawn, sapienceLevel); //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.FactionOrExtraHomeFaction;
            Map     oMap     = original.Map;


            //apply any other post tf effects
            ApplyPostTfEffects(original, animalToSpawn, request);

            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, animalToSpawn, 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);
        }
Example #30
0
        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);
            }
        }