/// <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(); }
/// <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); }
/// <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(); }
/// <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(); }
/// <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); }
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(); }
/// <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(); }
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(); }