private static void ValidateApparelForChangedPawn([NotNull] Pawn pawn, [NotNull] ThingDef oldRace)
        {
            Pawn_ApparelTracker apparel = pawn.apparel;

            if (apparel == null)
            {
                return;
            }

            _apparelCache.Clear();
            _apparelCache.AddRange(apparel.WornApparel.MakeSafe());


            foreach (Apparel ap in _apparelCache) //use a copy so we can remove them safely while iterating
            {
                if (!ApparelUtility.HasPartsToWear(pawn, ap.def))
                {
                    if (DebugLogUtils.ShouldLog(LogLevel.Messages))
                    {
                        Log.Message($"removing {ap.Label}");
                    }

                    if (apparel.TryDrop(ap))
                    {
                        apparel.Remove(ap);
                    }
                }
            }
        }
        public override bool GizmoDisabled(out string reason)
        {
            if (base.GizmoDisabled(out reason))
            {
                return(true);
            }

            if (pawn.GetMutagenicAbilityLevel() < def.level)
            {
                reason = AbilityUtilities.NOT_HIGH_ENOUGH_LEVEL_LABEL.Translate(def.level);
                return(true);
            }

            var entropyTracker = pawn.GetComp <MutagenicEntropyTracker>();

            if (entropyTracker == null)
            {
                reason = $"{pawn.Name} does not have a mutagenic entropy tracker! this should not happen!";
                DebugLogUtils.Warning(reason);
                return(true);
            }

            if (!entropyTracker.CanAcceptEntropyAmount(def.GetMutagenicEntropyGain()))
            {
                reason = AbilityUtilities.TOO_MUCH_ENTROPY_LABEL.Translate(def.label);
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// called every tick
        /// </summary>
        public override void CompTick()
        {
            base.CompTick();

            if (_triggered)
            {
                return;
            }
            _triggered = true;
            try
            {
                var pawn     = (Pawn)parent;
                var sTracker = pawn?.GetSapienceTracker();
                if (sTracker == null)
                {
                    DebugLogUtils.Warning($"unable to get sapience tracker on pawn {pawn?.LabelShort ?? "NULL"}");
                    return;
                }

                MakeMergedPawn(sTracker);
            }
            catch (InvalidCastException e)
            {
                Log.Error($"unable to case {parent.GetType().Name} to {nameof(Pawn)}!\n{e}");
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Posts the spawn setup.
        /// </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;
            }

            try
            {
                var pawn     = (Pawn)parent;
                var sTracker = pawn?.GetSapienceTracker();
                if (sTracker == null)
                {
                    DebugLogUtils.Warning($"unable to get sapience tracker on pawn {pawn?.LabelShort ??"NULL"}");
                    return;
                }

                MakeMergedPawn(sTracker);
            }
            catch (InvalidCastException e)
            {
                Log.Error($"unable to case {parent.GetType().Name} to {nameof(Pawn)}!\n{e}");
            }
        }
Esempio n. 5
0
            static void AddInteractionThoughts([NotNull] Pawn recipient, [NotNull] InteractionDef intDef, bool __result)
            {
                if (!__result)
                {
                    return;
                }
                if ((recipient.IsFormerHuman() || recipient.GetSapienceState()?.StateDef == SapienceStateDefOf.Animalistic) && recipient.needs?.mood != null)
                {
                    var memory = intDef.GetModExtension <InstinctEffector>()?.thought;  //hacky, should come up with a better solution eventually
                    if (memory == null)
                    {
                        return;
                    }

                    if (DebugLogUtils.ShouldLog(LogLevel.Messages))
                    {
                        var msg = $"giving {recipient.Name} memory {memory.defName}";
                        Log.Message(msg);
                    }


                    //social thoughts to?
                    recipient.TryGainMemory(memory);
                }
            }
Esempio n. 6
0
        private void TryAddMutationsToPawn([NotNull] Pawn original, [CanBeNull] Hediff requestCause,
                                           [NotNull] PawnKindDef requestOutputDef)
        {
            MorphDef mDef = null;

            if (requestCause != null) //first check the cause
            {
                foreach (MorphDef morphDef in MorphDef.AllDefs)
                {
                    if (morphDef.fullTransformation == requestCause.def || morphDef.partialTransformation == requestCause.def)
                    {
                        mDef = morphDef;
                        goto applyMutations; //ugly, but it's the easiest solution
                    }
                }
            }

            mDef = MorphUtilities.TryGetBestMorphOfAnimal(requestOutputDef.race);

            if (mDef == null)
            {
                DebugLogUtils.LogMsg(LogLevel.Messages, $"could not apply mutations to {original} with cause {requestCause?.def?.defName ?? "NULL"} and target {requestOutputDef.defName}");
                return;
            }


applyMutations:
            MutationUtilities.AddAllMorphMutations(original, mDef);
        }
Esempio n. 7
0
 /// <summary>
 /// Exits the current sapience state.
 /// </summary>
 public void ExitState()
 {
     if (_sapienceState == null)
     {
         DebugLogUtils.Warning($"trying to exit sapience state in {Pawn.Name} but they aren't in one");
         return;
     }
     _sapienceState.Exit();
     _sapienceState = null;
 }
        /// <summary>
        ///     Generates the genomes.
        /// </summary>
        internal static void GenerateGenomes()
        {
            if (_allImplicitGenomes != null)
            {
                Log.Error("trying to generate genomes more then once!");

                return;
            }

            _allImplicitGenomes = new List <ThingDef>();
            var catDef = PMThingCategoryDefOf.PM_MutationGenome;

            catDef.childThingDefs = catDef?.childThingDefs ?? new List <ThingDef>();

            foreach (MutationCategoryDef mDef in AllImplicitGenomeMutations)
            {
                ThingDef tDef = GenerateMutationGenome(mDef);
                mDef.implicitGenomeDef = tDef;
                _allImplicitGenomes.Add(tDef);
            }

            foreach (PawnKindDef pk in AllPKsWithGenomes)
            {
                ThingDef tDef = GenerateAnimalGenome(pk);
                _genomeDict[pk] = tDef;
                _allImplicitGenomes.Add(tDef);
            }


            foreach (ThingDef allImplicitGenome in _allImplicitGenomes)
            {
                try
                {
                    Init(allImplicitGenome);
                    DefDatabase <ThingDef> .Add(allImplicitGenome);

                    catDef.childThingDefs.Add(allImplicitGenome);
                }
                catch (Exception e)
                {
                    Log.Error($"could not initialize genome {allImplicitGenome.defName ?? "NO DEF NAME"}\n{e}");
                }
            }

            if (DebugLogUtils.ShouldLog(LogLevel.Messages))
            {
                var builder = new StringBuilder();
                builder.Append($"Generated {_allImplicitGenomes.Count} genomes!:");
                builder.AppendLine(_allImplicitGenomes.Join(t => t.defName, "\n"));
                Log.Message(builder.ToString());
            }

            ResourceCounter.ResetDefs();
        }
Esempio n. 9
0
        private static void MassPatchFormerHumanChecks([NotNull] Harmony harmonyInstance)
        {
            var staticFlags   = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
            var instanceFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;



            List <MethodInfo> methodsToPatch = new List <MethodInfo>();

            //bed stuff
            var bedUtilType     = typeof(RestUtility);
            var canUseBedMethod = bedUtilType.GetMethod(nameof(RestUtility.CanUseBedEver), staticFlags);

            methodsToPatch.Add(canUseBedMethod);

            //animal tabs
            var methods = typeof(MainTabWindow_Animals).GetNestedTypes(staticFlags | instanceFlags)//looking for delegates used by the animal tab
                          .Where(t => t.IsCompilerGenerated())
                          .SelectMany(t => t.GetMethods(instanceFlags).Where(m => m.HasSignature(typeof(Pawn))));

            methodsToPatch.AddRange(methods);

            //map pawns
            methods = typeof(MapPawns).GetMethods(instanceFlags).Where(m => m.HasSignature(typeof(Faction)));
            methodsToPatch.AddRange(methods);


            //jobs and toils
            methodsToPatch.Add(typeof(JobDriver_Ingest).GetMethod("PrepareToIngestToils", instanceFlags));

            //now patch them
            foreach (MethodInfo methodInfo in methodsToPatch)
            {
                if (methodInfo == null)
                {
                    continue;
                }
                harmonyInstance.ILPatchCommonMethods(methodInfo);
            }

            StringBuilder builder = new StringBuilder();

            builder.AppendLine("Patched:");
            foreach (MethodInfo methodInfo in methodsToPatch)
            {
                if (methodInfo == null)
                {
                    continue;
                }
                builder.AppendLine($"{methodInfo.Name}");
            }
            Log.Message(builder.ToString());
            DebugLogUtils.LogMsg(LogLevel.Messages, builder.ToString());
        }
Esempio n. 10
0
        private static void MassPatchFormerHumanChecks([NotNull] Harmony harmonyInstance)
        {
            var staticFlags   = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
            var instanceFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;



            List <MethodInfo> methodsToPatch = new List <MethodInfo>();

            //bed stuff
            var bedUtilType     = typeof(RestUtility);
            var canUseBedMethod = bedUtilType.GetMethod(nameof(RestUtility.CanUseBedEver), staticFlags);

            methodsToPatch.Add(canUseBedMethod);



            //map pawns
            var methods = typeof(MapPawns).GetMethods(instanceFlags).Where(m => m.HasSignature(typeof(Faction)));

            methodsToPatch.AddRange(methods);


            //jobs and toils
            methodsToPatch.Add(typeof(JobDriver_Ingest).GetMethod("PrepareToIngestToils", instanceFlags));
            methodsToPatch.Add(typeof(GatheringWorker_MarriageCeremony).GetMethod("IsGuest", instanceFlags));

            //now patch them
            foreach (MethodInfo methodInfo in methodsToPatch)
            {
                if (methodInfo == null)
                {
                    continue;
                }
                harmonyInstance.ILPatchCommonMethods(methodInfo);
            }

            StringBuilder builder = new StringBuilder();

            builder.AppendLine("Patched:");
            foreach (MethodInfo methodInfo in methodsToPatch)
            {
                if (methodInfo == null)
                {
                    continue;
                }
                builder.AppendLine($"{methodInfo.Name}");
            }
            Log.Message(builder.ToString());
            DebugLogUtils.LogMsg(LogLevel.Messages, builder.ToString());
        }
 /// <summary>
 /// Exits the current sapience state.
 /// </summary>
 /// <param name="recalculateComps">if set to <c>true</c> dynamic components will be recalculated after exiting the state.</param>
 public void ExitState(bool recalculateComps = true)
 {
     if (_sapienceState == null)
     {
         DebugLogUtils.Warning($"trying to exit sapience state in {Pawn.Name} but they aren't in one");
         return;
     }
     _sapienceState.Exit();
     _sapienceState = null;
     if (recalculateComps)
     {
         PawnComponentsUtility.AddAndRemoveDynamicComponents(Pawn);
     }
 }
Esempio n. 12
0
        public override void EjectContents() //should refactor the mutagenic chamber, make it a state machine
        {
            DebugLogUtils.Assert(innerContainer.Count == 1, "innerContainer.Count == 1");

            var pawn = (Pawn)innerContainer[0];

            if (pawn == null)
            {
                Log.Warning($"mutagenic chamber ejecting nothing");

                return;
            }



            if (IsFinished)
            {
                TransformPawn(pawn);
            }
            else
            {
                base.EjectContents();
                if (!Destroyed)
                {
                    SoundDefOf.CryptosleepCasket_Eject.PlayOneShot(SoundInfo.InMap(new TargetInfo(base.Position, base.Map)));
                    fuelComp.ConsumeFuel(fuelComp.Fuel);
                }


                if (_state != ChamberState.MergeOutOf || (linkTo?.daysIn ?? 0) < 1)
                {
                    pawn.health.AddHediff(Hediffs.MorphTransformationDefOf.FullRandomTFAnyOutcome);
                }

                pawn.health.AddHediff(Hediffs.MorphTransformationDefOf.FullRandomTFAnyOutcome);
                if (_state == ChamberState.MergeInto)
                {
                    linkTo?.EjectContents();
                }
            }

            _state = ChamberState.Idle;
            daysIn = 0;
        }
Esempio n. 13
0
            static bool SubstituteInteraction(Pawn recipient, ref InteractionDef intDef, Pawn ___pawn)
            {
                var            ext = intDef.GetModExtension <InteractionGroupExtension>();
                InteractionDef alt = ext?.TryGetAlternativeFor(___pawn, recipient);

                if (alt != null)
                {
                    if (DebugLogUtils.ShouldLog(LogLevel.Messages))
                    {
                        var msg = $"substituting {alt.defName} for {intDef.defName} on {___pawn.Name} -> {recipient.Name}";
                        Log.Message(msg);
                    }


                    intDef = alt;
                }

                return(true);
            }
Esempio n. 14
0
        private static void CheckForObsoletedComponents()
        {
            IEnumerable <HediffDef> obsoleteHediffTypes = DefDatabase <HediffDef>
                                                          .AllDefs.Where(h => h.hediffClass.HasAttribute <ObsoleteAttribute>());

            //get all obsoleted hediffs in use

            foreach (HediffDef obsoleteDef in obsoleteHediffTypes)
            {
                Log.Warning($"obsolete hediff {obsoleteDef.hediffClass.Name} in {obsoleteDef.defName}");
            }
            var tmp = new List <string>();

            foreach (HediffDef hediffDef in DefDatabase <HediffDef> .AllDefs)
            {
                IEnumerable <HediffGiver> obsoleteGivers =
                    hediffDef.GetAllHediffGivers().Where(g => g.GetType().HasAttribute <ObsoleteAttribute>());
                var builder = new StringBuilder();

                builder.AppendLine($"in {hediffDef.defName}");
                foreach (HediffGiver obsoleteGiver in obsoleteGivers)
                {
                    builder.AppendLine($"obsolete hediff giver: {obsoleteGiver.GetType().Name}".Indented());
                }
                IEnumerable <HediffGiver> giversGivingBadHediffs = hediffDef
                                                                   .GetAllHediffGivers() //find hediff giver that are giving obsolete hediffs
                                                                   .Where(g => g.hediff?.GetType().HasAttribute <ObsoleteAttribute>()
                                                                          ?? false);

                foreach (HediffGiver giversGivingBadHediff in giversGivingBadHediffs)
                {
                    tmp.Add($"giver {giversGivingBadHediff.GetType().Name} is giving obsolete hediff {giversGivingBadHediff.hediff.defName}");
                }


                if (tmp.Count > 0)
                {
                    builder.Append(string.Join("\n", tmp.ToArray()).Indented());
                    tmp.Clear();
                    DebugLogUtils.Warning(builder.ToString());
                }
            }
        }
Esempio n. 15
0
        /// <summary>
        ///     Generates the genomes.
        /// </summary>
        internal static void GenerateGenomes()
        {
            if (_allImplicitGenomes != null)
            {
                Log.Error("trying to generate genomes more then once!");

                return;
            }

            _allImplicitGenomes = new List <ThingDef>();


            foreach (MutationCategoryDef mDef in AllImplicitGenomeMutations)
            {
                ThingDef tDef = GenerateMutationGenome(mDef);
                mDef.implicitGenomeDef = tDef;
                _allImplicitGenomes.Add(tDef);
            }

            foreach (PawnKindDef pk in AllPKsWithGenomes)
            {
                ThingDef tDef = GenerateAnimalGenome(pk);
                _genomeDict[pk] = tDef;
                _allImplicitGenomes.Add(tDef);
            }


            foreach (ThingDef allImplicitGenome in _allImplicitGenomes)
            {
                GiveShortHash(allImplicitGenome);
                DefDatabase <ThingDef> .Add(allImplicitGenome);
            }

            if (DebugLogUtils.ShouldLog(LogLevel.Messages))
            {
                var builder = new StringBuilder();
                builder.Append($"Generated {_allImplicitGenomes.Count} genomes!:");
                builder.AppendLine(_allImplicitGenomes.Join(t => t.defName, "\n"));
                Log.Message(builder.ToString());
            }
        }
Esempio n. 16
0
        /// <summary>
        /// change the race of the pawn back to human
        /// </summary>
        /// <param name="pawn"></param>
        public static void RevertPawnToHuman([NotNull] Pawn pawn)
        {
            var race = pawn.def;

            var human = ThingDefOf.Human;

            if (race == human)
            {
                return;                //do nothing
            }
            var  oldMorph = pawn.def.GetMorphOfRace();
            bool isHybrid = oldMorph != null;


            DebugLogUtils.Assert(isHybrid, "pawn.IsHybridRace()");
            if (!isHybrid)
            {
                return;
            }

            var storedGraphics = pawn.GetComp <GraphicSys.InitialGraphicsComp>();

            storedGraphics.RestoreGraphics();

            ChangePawnRace(pawn, human);


            var morphRThought = oldMorph.transformSettings?.revertedMemory;

            morphRThought = morphRThought ?? PMThoughtDefOf.DefaultMorphRevertsToHuman;

            if (morphRThought != null)
            {
                pawn.TryGainMemory(morphRThought);
            }
            var messageStr = RACE_REVERT_MESSAGE_ID.Translate(pawn.LabelShort).CapitalizeFirst();

            Messages.Message(messageStr, pawn, MessageTypeDefOf.NeutralEvent);
        }
Esempio n. 17
0
        /// <summary>
        ///     notifies this instance that a connector was added
        /// </summary>
        /// <param name="comp">The comp.</param>
        /// <exception cref="ArgumentNullException">comp</exception>
        public void NotifyConnectorAdded([NotNull] SlurryNetComp comp)
        {
            if (comp == null)
            {
                throw new ArgumentNullException(nameof(comp));
            }

            DebugLogUtils.LogMsg(LogLevel.Messages, $"adding connector for '{comp.parent.Label}'");

            if (comp.Network != null || Nets.Any(n => n.Connectors.Contains(comp)))
            {
                Log.Error($"adding slurry comp {comp.parent.Label} which is already part of a network");
                return;
            }

            List <SlurryNet> neighbors = comp.GetAdjacentSlurryComps()
                                         .Select(n => n.Network)
                                         .Where(n => n != null)
                                         .Distinct()
                                         .ToList();

            if (neighbors.Count == 1)
            {
                neighbors[0].Register(comp);
            }
            else
            {
                foreach (SlurryNet slurryNet in neighbors)
                {
                    DestroyNet(slurryNet);
                }

                SlurryNet net = CreateSlurryNetFrom(comp, null);
                _nets.Add(net);
            }
        }
Esempio n. 18
0
 public T this[int index]
 {
     get
     {
         lock (m_lock)
         {
             try
             {
                 DebugLogEntry.Register(new MyDebugLogEntry(MyDebugLogEntry.Action.Index, m_head, m_tail, index));
                 if (m_tail + index >= m_head)
                 {
                     throw new ArgumentOutOfRangeException("index");
                 }
                 return(m_buffer[m_tail + index]);
             }
             catch (Exception ex)
             {
                 DebugLogEntry.Register(new DebugLogEntryString(ex.GetType().Name + ", " + ex.Message));
                 DebugLogUtils.DumpToFile();
                 throw;
             }
         }
     }
 }
Esempio n. 19
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);
        }
 static void HandlePrisoner(Pawn pawn)
 {
     pawn.guest.Released = true;
     pawn.guest.SetGuestStatus(null);
     DebugLogUtils.Assert(!pawn.guest.IsPrisoner, $"{pawn.Name} is being cleaned up but is still a prisoner");
 }