/// <summary>
        /// do a steady effect on the given cell
        /// </summary>
        /// <param name="c"></param>
        /// <param name="map"></param>
        public override void DoCellSteadyEffects(IntVec3 c, Map map)
        {
            base.DoCellSteadyEffects(c, map);

            if (c.Roofed(map))
            {
                return;
            }

            var thingList = c.GetThingList(map);

            RandUtilities.PushState(); // MP compatibility check for rand usage.

            for (var index = thingList.Count - 1; index > 0; index--)
            {
                Thing thing = thingList[index];
                if (!(thing is Plant plant))
                {
                    continue;
                }
                if (plant.def.IsMutantPlant())
                {
                    continue;
                }

                if (Rand.Value < PLANT_SUBSTITUTION_CHANCE)
                {
                    SubstitutePlant(plant);
                }
            }

            RandUtilities.PopState();
        }
示例#2
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();
        }
        /// <summary>Tries to transform the pawn</summary>
        /// <param name="pawn">The pawn.</param>
        /// <param name="cause">The cause.</param>
        /// <returns></returns>
        public bool TryTransform(Pawn pawn, Hediff cause)
        {
            RandUtilities.PushState();
            bool changed = false;

            try
            {
                float chance = changeChance < 0 // If changeChance wasn't overriden use the default from the settings.
                                   ? LoadedModManager.GetMod <PawnmorpherMod>().GetSettings <PawnmorpherSettings>().transformChance
                                   : changeChance;

                //apply the new stat
                chance *= pawn.GetStatValue(PMStatDefOf.TransformationSensitivity);
                chance  = Mathf.Clamp(chance, 0, 100);


                if (Rand.Range(0, 100) < chance)
                {
                    changed = TransformPawn(pawn, cause);
                }
            }
            finally
            {
                RandUtilities.PopState();
            }

            return(changed);
        }
示例#4
0
 /// <summary>
 /// called after every tick
 /// </summary>
 public override void Tick()
 {
     if (_countdownStarted && Pawn.IsHashIntervalTick(60) && RandUtilities.MtbDaysEventOccured(PERMANENTLY_FERAL_MTB))
     {
         _countdownStarted = false;
         MakePermanentlyFeral();
     }
 }
示例#5
0
        /// <summary> The function that does the heavy lifting for a HediffGiver. </summary>
        /// <param name="pawn"> The pawn the parent hediff is applied to. </param>
        /// <param name="cause"> The parent hediff where this HediffGiver is located in. </param>
        public override void OnIntervalPassed(Pawn pawn, [NotNull] Hediff cause)
        {
            // Push a multiplay-safe randomization seed.
            RandUtilities.PushState();


            var   singleComp = cause.TryGetComp <HediffComp_Single>();
            float mult       = singleComp?.stacks
                               ?? 1; //the more stacks of partial morphs the pawn has the faster the mutation rate should be

            mult *= pawn.GetStatValue(PMStatDefOf.MutagenSensitivity);
            mult *= singleComp?.Props?.mutationRateMultiplier ?? 1;
            mult  = Mathf.Max(0.001f, mult); //prevent division by zero


            // After roughly this duration, try to apply the hediff if the pawn is of human-like intelligence.
            if (Rand.MTBEventOccurs(mtbDays / mult, mtbUnits, 30f) && pawn.RaceProps.intelligence == Intelligence.Humanlike)
            {
                //mutagen is what contains information like infect-ability of a pawn and post mutation effects
                MutagenDef mutagen = cause.def?.GetMutagenDef() ?? MutagenDefOf.defaultMutagen;

                // Check if this HediffGiver has the HediffComp_Single property (basically a dummy property that only comes into play in this function).
                var comp = singleComp;

                // If we haven't already tried to apply this giver's hediff and the pawn either passes a percentile roll or are of the right gender, try and apply the hediff.
                if (!_triggered.TryGetValue(cause) && (gender == pawn.gender || Rand.RangeInclusive(0, 100) <= chance) && TryApply(pawn, mutagen, null, cause))
                {
                    _triggered[cause] = true;
                    DoMutationAddedEffects(pawn);

                    // If the parent has the single comp, decrement it's current count and remove it if it's out of charges.
                    if (comp != null)
                    {
                        comp.stacks--;
                        if (comp.stacks <= 0)
                        {
                            pawn.health.RemoveHediff(cause);
                        }
                    }
                }
                else
                {
                    _triggered[cause] = true;
                    // If the giver had the single comp, clear the list so it can try and apply the hediff again.
                    // While this does prevent the partial hediffs from getting "stuck", it does mean that they
                    // can apply a hediff that already exists or failed because of the %chance rule. Need to find
                    // a better solution to this problem eventually.
                    if (comp != null)
                    {
                        ClearHediff(cause);
                    }
                }
            }

            // Pop the seed to restore balance to the universe (and the game).
            RandUtilities.PopState();
        }
示例#6
0
 /// <summary>
 ///     called after every tick
 /// </summary>
 public override void Tick()
 {
     if (_waiting && RandUtilities.MtbDaysEventOccured(MTB))
     {
         if (!CanRemove)
         {
             return;
         }
         Tracker?.ExitState();
     }
 }
示例#7
0
        /// <summary>Adds the severity.</summary>
        public void AddSeverity()
        {
            RandUtilities.PushState();

            if (Rand.MTBEventOccurs(Props.mtbDays, 60000f, 60f) && !triggered && Pawn.health.hediffSet.HasHediff(Props.hediff))
            {
                HealthUtility.AdjustSeverity(Pawn, Props.hediff, Props.severity);
                triggered = true;
            }

            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;
            }
            RandUtilities.PushState();


            RandUtilities.PopState();
        }
示例#9
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)
        {
            RandUtilities.PushState();

            var enumer = GenerateThingEnumer(forTile, forFaction).ToList();

            RandUtilities.PopState();
            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);
        }
示例#10
0
        void CheckForBrainDamage(Pawn meld, Pawn human0, Pawn human1)
        {
            RandUtilities.PushState();

            var brains = meld.health.hediffSet.GetNotMissingParts()
                         .Where(p => p.def.tags.Contains(BodyPartTagDefOf.ConsciousnessSource))
                         .ToList();

            if (brains.Count != 2)
            {
                var pawn = Rand.Value < 0.5f ? human0 : human1;
                //var brain = pawn.health.hediffSet.GetBrain();
                DamageInfo dInfo = new DamageInfo(DamageDefOf.Stab, 100, 1);
                pawn.Kill(dInfo);
            }

            RandUtilities.PopState();
        }
示例#11
0
        /// <summary>Tries to give transformations</summary>
        protected virtual void TryGiveTransformations()
        {
            if (CurStage == null)
            {
                return;
            }

            RandUtilities.PushState();

            foreach (var tfGiver in CurStage.GetAllTransformers())
            {
                if (tfGiver.TryTransform(pawn, this))
                {
                    break; //try each one, one by one. break at first one that succeeds
                }
            }
            RandUtilities.PopState();
        }
示例#12
0
        /// <summary>
        ///     called after every tick
        /// </summary>
        public override void Tick()
        {
            if (_doPostInit)
            {
                //need to defer this to the first tick after being added so Tracker has a chance to update correctly
                _waiting    = Tracker.SapienceLevel == SapienceLevel.Sapient;
                _doPostInit = false;
            }

            if (_waiting && RandUtilities.MtbDaysEventOccured(MTB))
            {
                if (!CanRemove)
                {
                    return;
                }
                Tracker?.ExitState();
            }
        }
        public override void OnIntervalPassed(Pawn pawn, Hediff cause)
        {
            if (pawn.health.hediffSet.hediffs.Any(x => hediffDefs.Any(y => y == x.def)))
            {
                return;
            }

            RandUtilities.PushState();

            if (Rand.RangeInclusive(0, 100) <= completeChance)
            {
                hediffDef = hediffDefsComplete.RandomElement();
            }
            else
            {
                hediffDef = hediffDefs.RandomElement();
            }

            Hediff hediff = HediffMaker.MakeHediff(hediffDef, pawn);
            float  num;

            if (severity > 0f)
            {
                num = severity;
            }
            else
            {
                num = hediffDef.initialSeverity;
            }

            if (divideByBodySize)
            {
                num /= pawn.BodySize;
            }

            AddictionUtility.ModifyChemicalEffectForToleranceAndBodySize(pawn, toleranceChemical, ref num);
            hediff.Severity = num;
            pawn.health.AddHediff(hediff);

            RandUtilities.PopState();
        }
        private void Produce(int amount, float chance, ThingDef resource, ThingDef rareResource, ThoughtDef stageThought)
        {
            RandUtilities.PushState();

            MemoryThoughtHandler thoughts   = Pawn.needs.mood.thoughts.memories;
            EtherState           etherState = Pawn.GetEtherState();

            HatchingTicker = 0;
            var    thingCount     = 0;
            var    rareThingCount = 0;
            Aspect infusedAspect  = Pawn.GetAspectTracker()?.GetAspect(AspectDefOf.MutagenInfused);

            int?sIndex = infusedAspect?.StageIndex;


            for (var i = 0; i < amount; i++)
            {
                bool shouldProduceRare;
                switch (sIndex)
                {
                case null:
                    shouldProduceRare = Rand.RangeInclusive(0, 100) <= chance;
                    break;

                case 0:
                    shouldProduceRare = true;
                    break;

                case 1:
                    shouldProduceRare = false;
                    break;

                case 2:
                    return;     //produce nothing

                default:
                    throw new ArgumentOutOfRangeException(sIndex.Value.ToString());
                }

                if (shouldProduceRare && rareResource != null)
                {
                    rareThingCount++;
                }
                else
                {
                    thingCount++;
                }
            }

            Thing thing = ThingMaker.MakeThing(resource);

            thing.stackCount = thingCount;
            if (thing.stackCount > 0)
            {
                GenPlace.TryPlaceThing(thing, Pawn.PositionHeld, Pawn.Map, ThingPlaceMode.Near);
            }

            if (rareResource != null)
            {
                Thing rareThing = ThingMaker.MakeThing(rareResource);
                rareThing.stackCount = rareThingCount;
                if (rareThing.stackCount > 0)
                {
                    GenPlace.TryPlaceThing(rareThing, Pawn.PositionHeld, Pawn.Map, ThingPlaceMode.Near);
                }
            }

            if (etherState == EtherState.None)
            {
                if (Rand.RangeInclusive(0, 100) <= bondChance)
                {
                    GiveEtherState(EtherState.Bond);
                    etherState = EtherState.Bond;
                    Find.LetterStack.ReceiveLetter(
                        "LetterHediffFromEtherBondLabel".Translate(Pawn).CapitalizeFirst(),
                        "LetterHediffFromEtherBond".Translate(Pawn).CapitalizeFirst(),
                        LetterDefOf.NeutralEvent, Pawn);
                }
                else if (Rand.RangeInclusive(0, 100) <= brokenChance)
                {
                    GiveEtherState(EtherState.Broken);
                    etherState = EtherState.Broken;
                    Find.LetterStack.ReceiveLetter(
                        "LetterHediffFromEtherBrokenLabel".Translate(Pawn).CapitalizeFirst(),
                        "LetterHediffFromEtherBroken".Translate(Pawn).CapitalizeFirst(),
                        LetterDefOf.NeutralEvent, Pawn);
                }
            }

            if (stageThought != null)
            {
                thoughts.TryGainMemory(stageThought);
            }

            ThoughtDef addThought;

            switch (etherState)
            {
            case EtherState.None:
                addThought = Props.genderAversion == Pawn.gender ? Props.wrongGenderThought ?? Props.thought : Props.thought;
                break;

            case EtherState.Broken:
                addThought = Props.etherBrokenThought;
                break;

            case EtherState.Bond:
                addThought = Props.etherBondThought;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            if (addThought != null)
            {
                thoughts.TryGainMemory(addThought);
            }

            if (etherState == EtherState.None)
            {
                brokenChance += 0.5f;
                bondChance   += 0.2f;
            }
            totalProduced += rareThingCount + thingCount;
            RandUtilities.PopState();
        }
示例#15
0
 static MutagenicStone()
 {
     _p = RandUtilities.GetUniformProbability(MTTH_PLANT_MUTATE, 4.16f); //one long tick is ~4.16 seconds
 }