public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients) { // We don't check if the surgery fails, because even if the surgery is a failure the fetus will still die if (billDoer != null) { TaleRecorder.RecordTale(TaleDefOf.DidSurgery, new object[] { billDoer, pawn }); if (base.CheckSurgeryFail(billDoer, pawn, ingredients, part) == false) { if (PawnUtility.ShouldSendNotificationAbout(pawn) || PawnUtility.ShouldSendNotificationAbout(billDoer)) { string text; if (!this.recipe.successfullyRemovedHediffMessage.NullOrEmpty()) { text = string.Format(this.recipe.successfullyRemovedHediffMessage, billDoer.LabelShort, pawn.LabelShort); } else { text = "MessageSuccessfullyRemovedHediff".Translate(new object[] { billDoer.LabelShort, pawn.LabelShort, this.recipe.removesHediff.label }); } Messages.Message(text, pawn, MessageSound.Benefit); } } } Hediff_HumanPregnancy preggo = (Hediff_HumanPregnancy)pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("HumanPregnancy")); if (preggo.IsLateTerm()) { // Give bad thoughts related to late abortions pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("LateTermAbortion"), null); if (preggo.GestationProgress >= 0.97f) { Thought_Memory abortion_thought = pawn.needs.mood.thoughts.memories.OldestMemoryOfDef(ThoughtDef.Named("LateTermAbortion")); if (abortion_thought == null) { Log.Error("ChildrenMod: Failed to add late term abortion thought!"); } // Very late term abortion abortion_thought.SetForcedStage(abortion_thought.CurStageIndex + 1); } // Give bad thoughts related to late abortions pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("LateTermAbortion"), null); if (preggo.GestationProgress >= 0.97f) { Thought_Memory abortion_thought = pawn.needs.mood.thoughts.memories.OldestMemoryOfDef(ThoughtDef.Named("LateTermAbortion")); // Very late term abortion abortion_thought.SetForcedStage(abortion_thought.CurStageIndex + 1); } // Remove the fetus preggo.Miscarry(true); } else { pawn.health.RemoveHediff(preggo); } }
// Token: 0x06000053 RID: 83 RVA: 0x000040E4 File Offset: 0x000022E4 public void TryHealRandomOldWound() { var healAmount = AYProps.RegenHealVal; var candidates = new List <Hediff>(); var pawn = Pawn; List <Hediff> list; if (pawn == null) { list = null; } else { var health = pawn.health; list = health?.hediffSet.hediffs; } var hediffs = list; if (hediffs != null && hediffs.Count > 0) { foreach (var hediff in hediffs) { if (Def.defName == "AYAloeCreamHigh") { if (hediff.def == HediffDefOf.Burn) { candidates.Add(hediff); } } else if (Def.defName == "AYScarCreamHigh") { if (hediff.IsPermanent() || hediff.def == HediffDefOf.Burn) { candidates.Add(hediff); } } else if (hediff.IsPermanent()) { candidates.Add(hediff); } } } if (candidates.Count <= 0) { return; } candidates.TryRandomElement(out var hediffToHeal); if (hediffToHeal == null) { return; } if (hediffToHeal.IsTended()) { healAmount = (int)(healAmount * 1.2f); var healfactor = GetHealFactor(Def, hediffToHeal); if (healfactor > 0f) { healAmount = (int)(healAmount * healfactor); if (healAmount < 1) { healAmount = 1; } } } if (hediffToHeal.Severity - healAmount <= 0f && PawnUtility.ShouldSendNotificationAbout(Pawn)) { Messages.Message( "Apothecary.WoundHealed".Translate(parent.LabelCap, Pawn.LabelShort, hediffToHeal.Label, Pawn.Named("PAWN")), Pawn, MessageTypeDefOf.PositiveEvent); } if (hediffToHeal.Severity - healAmount > 0f) { hediffToHeal.Severity -= healAmount; return; } hediffToHeal.Severity = 0f; }
public int napLength = 5000 / 200; // 2 hours public override void HandleTick(SkillRecord sr, Pawn pawn) { if (pawn.Map == null) { return; } var boredomLevels = pawn.Map.GetComponent <BoredData>().boredomLevels; var napTimers = pawn.Map.GetComponent <BoredData>().napTimers; if (!boredomLevels.ContainsKey(pawn)) { boredomLevels.Add(pawn, 0.0f); napTimers.Add(pawn, 0); } Pawn_JobTracker jt = pawn.jobs; if (jt == null) // no jobs, maybe idle? doesn't encompass sleeping { BoredomUntick(pawn); return; } JobDriver curDriver = jt.curDriver; if (curDriver == null) // no driver, not sure what this would mean but seems to happen { BoredomUntick(pawn); return; } if (curDriver.asleep && napTimers[pawn] > 0) // dude's taking a nap from boredom { Log.Message(napTimers[pawn].ToString()); if (napTimers[pawn] == 1) // wake up { RestUtility.WakeUp(pawn); } napTimers[pawn]--; BoredomUntick(pawn); return; } napTimers[pawn] = 0; // just in case the pawn's awake without a 0 nap timer if (pawn.skills == null) // no skills { BoredomUntick(pawn); return; } SkillDef active = curDriver.ActiveSkill; if (active != sr.def) // the skill with bored passion isn't the one being used { BoredomUntick(pawn); return; } // ok, the pawn's awake and it's doing something boring BoredomTick(pawn); Log.Message(boredomLevels[pawn].ToString()); float boredomLevel = boredomLevels[pawn]; if (boredomLevel > napPossibleThreshold) // pretty bored { float rand = Rand.Value * (1 - napPossibleThreshold); // [0, (1 - napThreshold)], something like [0, 0.4] if (rand < (boredomLevel - napPossibleThreshold)) // fall asleep { Job napJob = JobMaker.MakeJob(JobDefOf.LayDown, pawn.Position); napJob.forceSleep = true; pawn.jobs.StartJob(napJob, JobCondition.InterruptForced, null, true, true, null, new JobTag?(JobTag.InMentalState), false, false); if (PawnUtility.ShouldSendNotificationAbout(pawn)) { Messages.Message("DMessageBoredNap".Translate(sr.def.defName.ToLower(), pawn), pawn, MessageTypeDefOf.SilentInput, true); //Messages.Message("DMessageBoredNap".Translate(this.pawn.LabelShort, this.pawn), this.pawn, MessageTypeDefOf.NegativeEvent, true); } napTimers[pawn] = napLength; boredomLevels[pawn] *= 0.25f; } } }
public void HealthTick() { if (this.Dead) { return; } for (int i = this.hediffSet.hediffs.Count - 1; i >= 0; i--) { Hediff hediff = this.hediffSet.hediffs[i]; hediff.Tick(); hediff.PostTick(); } bool flag = false; for (int j = this.hediffSet.hediffs.Count - 1; j >= 0; j--) { Hediff hediff2 = this.hediffSet.hediffs[j]; if (hediff2.ShouldRemove) { this.hediffSet.hediffs.RemoveAt(j); hediff2.PostRemoved(); flag = true; } } if (flag) { this.Notify_HediffChanged(null); } if (this.Dead) { return; } this.immunity.ImmunityHandlerTick(); if (this.pawn.RaceProps.IsFlesh && this.pawn.IsHashIntervalTick(600) && (this.pawn.needs.food == null || !this.pawn.needs.food.Starving)) { bool flag2 = false; if (this.hediffSet.HasNaturallyHealingInjury()) { float num = 8f; if (this.pawn.GetPosture() != PawnPosture.Standing) { num += 4f; Building_Bed building_Bed = this.pawn.CurrentBed(); if (building_Bed != null) { num += building_Bed.def.building.bed_healPerDay; } } Hediff_Injury hediff_Injury = this.hediffSet.GetHediffs <Hediff_Injury>().Where(new Func <Hediff_Injury, bool>(HediffUtility.CanHealNaturally)).RandomElement <Hediff_Injury>(); hediff_Injury.Heal(num * this.pawn.HealthScale * 0.01f); flag2 = true; } if (this.hediffSet.HasTendedAndHealingInjury() && (this.pawn.needs.food == null || !this.pawn.needs.food.Starving)) { Hediff_Injury hediff_Injury2 = this.hediffSet.GetHediffs <Hediff_Injury>().Where(new Func <Hediff_Injury, bool>(HediffUtility.CanHealFromTending)).RandomElement <Hediff_Injury>(); float tendQuality = hediff_Injury2.TryGetComp <HediffComp_TendDuration>().tendQuality; float num2 = GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality)); hediff_Injury2.Heal(22f * num2 * this.pawn.HealthScale * 0.01f); flag2 = true; } if (flag2 && !this.HasHediffsNeedingTendByColony(false) && !HealthAIUtility.ShouldSeekMedicalRest(this.pawn) && !this.hediffSet.HasTendedAndHealingInjury() && PawnUtility.ShouldSendNotificationAbout(this.pawn)) { Messages.Message("MessageFullyHealed".Translate(new object[] { this.pawn.LabelCap }), this.pawn, MessageTypeDefOf.PositiveEvent); } } if (this.pawn.RaceProps.IsFlesh && this.hediffSet.BleedRateTotal >= 0.1f) { float num3 = this.hediffSet.BleedRateTotal * this.pawn.BodySize; if (this.pawn.GetPosture() == PawnPosture.Standing) { num3 *= 0.008f; } else { num3 *= 0.0008f; } if (Rand.Value < num3) { this.TryDropBloodFilth(); } } List <HediffGiverSetDef> hediffGiverSets = this.pawn.RaceProps.hediffGiverSets; if (hediffGiverSets != null && this.pawn.IsHashIntervalTick(60)) { for (int k = 0; k < hediffGiverSets.Count; k++) { List <HediffGiver> hediffGivers = hediffGiverSets[k].hediffGivers; for (int l = 0; l < hediffGivers.Count; l++) { hediffGivers[l].OnIntervalPassed(this.pawn, null); if (this.pawn.Dead) { return; } } } } }
protected override IEnumerable <Toil> MakeNewToils() { // Toil toil = new Toil(); toil.initAction = delegate { //Empty }; this.EndOnDespawnedOrNull(InquisitorIndex, JobCondition.Incompletable); this.EndOnDespawnedOrNull(PreacherIndex, JobCondition.Incompletable); //this.EndOnDespawnedOrNull(Build, JobCondition.Incompletable); yield return(Toils_Reserve.Reserve(PreacherIndex, this.job.def.joyMaxParticipants)); Toil gotoPreacher; gotoPreacher = Toils_Goto.GotoThing(PreacherIndex, PathEndMode.ClosestTouch); yield return(gotoPreacher); if (Preacher.jobs.curDriver.asleep) { Toil watchToil = new Toil(); watchToil.defaultCompleteMode = ToilCompleteMode.Delay; watchToil.defaultDuration = this.job.def.joyDuration; watchToil.AddPreTickAction(() => { this.pawn.rotationTracker.FaceCell(Preacher.Position); this.pawn.GainComfortFromCellIfPossible(); }); yield return(watchToil); } Action hitAction = delegate { Pawn prey = Preacher; bool surpriseAttack = this.firstHit; if (pawn.meleeVerbs.TryMeleeAttack(prey, this.job.verbToUse, surpriseAttack)) { if (!this.notifiedPlayer && PawnUtility.ShouldSendNotificationAbout(prey)) { this.notifiedPlayer = true; if (Prefs.PauseOnUrgentLetter && !Find.TickManager.Paused) { Find.TickManager.TogglePaused(); } Messages.Message("MessageAttackedByPredator".Translate(new object[] { prey.LabelShort, this.pawn.LabelShort, }).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatBig); } this.pawn.Map.attackTargetsCache.UpdateTarget(this.pawn); } this.firstHit = false; }; yield return(Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, hitAction).JumpIfDespawnedOrNull(TargetIndex.A, toil).FailOn(() => Find.TickManager.TicksGame > this.startTick + 5000 && (this.job.GetTarget(TargetIndex.A).Cell - this.pawn.Position).LengthHorizontalSquared > 4f)); yield return(toil); this.AddFinishAction(() => { //if (this.TargetB.HasThing) //{ // Find.Reservations.Release(this.job.targetC.Thing, pawn); //} }); }
public void HealthTick() { if (!Dead) { for (int num = hediffSet.hediffs.Count - 1; num >= 0; num--) { Hediff hediff = hediffSet.hediffs[num]; try { hediff.Tick(); hediff.PostTick(); } catch (Exception ex) { Log.Error("Exception ticking hediff " + hediff.ToStringSafe() + " for pawn " + pawn.ToStringSafe() + ". Removing hediff... Exception: " + ex); try { RemoveHediff(hediff); } catch (Exception arg) { Log.Error("Error while removing hediff: " + arg); } } } bool flag = false; for (int num2 = hediffSet.hediffs.Count - 1; num2 >= 0; num2--) { Hediff hediff2 = hediffSet.hediffs[num2]; if (hediff2.ShouldRemove) { hediffSet.hediffs.RemoveAt(num2); hediff2.PostRemoved(); flag = true; } } if (flag) { Notify_HediffChanged(null); } if (!Dead) { immunity.ImmunityHandlerTick(); if (pawn.RaceProps.IsFlesh && pawn.IsHashIntervalTick(600) && (pawn.needs.food == null || !pawn.needs.food.Starving)) { bool flag2 = false; if (hediffSet.HasNaturallyHealingInjury()) { float num3 = 8f; if (pawn.GetPosture() != 0) { num3 += 4f; Building_Bed building_Bed = pawn.CurrentBed(); if (building_Bed != null) { num3 += building_Bed.def.building.bed_healPerDay; } } Hediff_Injury hediff_Injury = hediffSet.GetHediffs <Hediff_Injury>().Where(HediffUtility.CanHealNaturally).RandomElement(); hediff_Injury.Heal(num3 * pawn.HealthScale * 0.01f); flag2 = true; } if (hediffSet.HasTendedAndHealingInjury() && (pawn.needs.food == null || !pawn.needs.food.Starving)) { Hediff_Injury hediff_Injury2 = hediffSet.GetHediffs <Hediff_Injury>().Where(HediffUtility.CanHealFromTending).RandomElement(); float tendQuality = hediff_Injury2.TryGetComp <HediffComp_TendDuration>().tendQuality; float num4 = GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality)); hediff_Injury2.Heal(8f * num4 * pawn.HealthScale * 0.01f); flag2 = true; } if (flag2 && !HasHediffsNeedingTendByPlayer() && !HealthAIUtility.ShouldSeekMedicalRest(pawn) && !hediffSet.HasTendedAndHealingInjury() && PawnUtility.ShouldSendNotificationAbout(pawn)) { Messages.Message("MessageFullyHealed".Translate(pawn.LabelCap, pawn), pawn, MessageTypeDefOf.PositiveEvent); } } if (pawn.RaceProps.IsFlesh && hediffSet.BleedRateTotal >= 0.1f) { float num5 = hediffSet.BleedRateTotal * pawn.BodySize; num5 = ((pawn.GetPosture() != 0) ? (num5 * 0.0004f) : (num5 * 0.004f)); if (Rand.Value < num5) { DropBloodFilth(); } } if (pawn.IsHashIntervalTick(60)) { List <HediffGiverSetDef> hediffGiverSets = pawn.RaceProps.hediffGiverSets; if (hediffGiverSets != null) { for (int i = 0; i < hediffGiverSets.Count; i++) { List <HediffGiver> hediffGivers = hediffGiverSets[i].hediffGivers; for (int j = 0; j < hediffGivers.Count; j++) { hediffGivers[j].OnIntervalPassed(pawn, null); if (pawn.Dead) { return; } } } } if (pawn.story != null) { List <Trait> allTraits = pawn.story.traits.allTraits; for (int k = 0; k < allTraits.Count; k++) { TraitDegreeData currentData = allTraits[k].CurrentData; if (currentData.randomDiseaseMtbDays > 0f && Rand.MTBEventOccurs(currentData.randomDiseaseMtbDays, 60000f, 60f)) { BiomeDef biome; if (pawn.Tile != -1) { biome = Find.WorldGrid[pawn.Tile].biome; } else { biome = DefDatabase <BiomeDef> .GetRandom(); } IncidentDef incidentDef = (from d in DefDatabase <IncidentDef> .AllDefs where d.category == IncidentCategoryDefOf.DiseaseHuman select d).RandomElementByWeightWithFallback((IncidentDef d) => biome.CommonalityOfDisease(d)); if (incidentDef != null) { string blockedInfo; List <Pawn> list = ((IncidentWorker_Disease)incidentDef.Worker).ApplyToPawns(Gen.YieldSingle(pawn), out blockedInfo); if (PawnUtility.ShouldSendNotificationAbout(pawn)) { if (list.Contains(pawn)) { Find.LetterStack.ReceiveLetter("LetterLabelTraitDisease".Translate(incidentDef.diseaseIncident.label), "LetterTraitDisease".Translate(pawn.LabelCap, incidentDef.diseaseIncident.label, pawn.Named("PAWN")).AdjustedFor(pawn), LetterDefOf.NegativeEvent, pawn); } else if (!blockedInfo.NullOrEmpty()) { Messages.Message(blockedInfo, pawn, MessageTypeDefOf.NeutralEvent); } } } } } } } } } }
void TickAction() { var fadeOff = Tools.PheromoneFadeoff(); var agitatedFadeoff = fadeOff / 4; var checkSmashableFadeoff = agitatedFadeoff / 2; var zombie = (Zombie)pawn; if (zombie.state == ZombieState.Emerging) { return; } var map = zombie.Map; if (zombie.Dead || zombie.Destroyed) { EndJobWith(JobCondition.InterruptForced); return; } if (zombie.state == ZombieState.ShouldDie) { EndJobWith(JobCondition.InterruptForced); zombie.Kill(null); return; } if (ZombieSettings.Values.zombiesDieVeryEasily) { if (zombie.health.hediffSet.GetHediffs <Hediff_Injury>().Any()) { zombie.Kill(null); return; } } if (zombie.Downed) { if (ZombieSettings.Values.zombiesDieVeryEasily || ZombieSettings.Values.doubleTapRequired == false) { zombie.Kill(null); return; } var walkCapacity = PawnCapacityUtility.CalculateCapacityLevel(zombie.health.hediffSet, PawnCapacityDefOf.Moving); var missingBrain = zombie.health.hediffSet.GetBrain() == null; if (walkCapacity < 0.25f || missingBrain) { zombie.Kill(null); return; } var injuries = zombie.health.hediffSet.GetHediffs <Hediff_Injury>(); foreach (var injury in injuries) { if (ZombieSettings.Values.zombiesDieVeryEasily) { zombie.Kill(null); return; } if (injury.IsOld() == false) { injury.Heal(injury.Severity + 0.5f); break; } } if (zombie.Downed) { return; } } // handling invalid destinations // if (destination.x == 0 && destination.z == 0) { destination = IntVec3.Invalid; } if (zombie.HasValidDestination(destination)) { return; } // if we are near targets then attack them // var enemy = CanAttack(); if (enemy != null) { destination = enemy.Position; zombie.state = ZombieState.Tracking; if (Constants.USE_SOUND) { var info = SoundInfo.InMap(enemy); SoundDef.Named("ZombieHit").PlayOneShot(info); } AttackThing(enemy, JobDefOf.AttackMelee); return; } // eat a downed or dead pawn // if (eatTarget == null) { eatTarget = CanIngest(out eatTargetIsCorpse); if (eatTarget != null) { eatTargetDied = eatTarget.Dead; } } if (eatTarget != null) { if (eatDelayCounter == 0) { if (eatTarget != lastEatTarget) { lastEatTarget = eatTarget; zombie.Drawer.rotator.FaceCell(eatTarget.Position); var zombieLeaner = zombie.Drawer.leaner as ZombieLeaner; if (zombieLeaner != null) { zombieLeaner.extraOffset = (eatTarget.Position.ToVector3() - zombie.Position.ToVector3()) * 0.5f; } Tools.CastThoughtBubble(pawn, Constants.EATING); } CastEatingSound(); } eatDelayCounter++; if (eatDelayCounter <= EatDelay) { return; } eatDelayCounter = 0; var bodyPartRecord = FirstEatablePart(eatTarget); if (bodyPartRecord != null) { var hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, eatTarget, bodyPartRecord); hediff_MissingPart.lastInjury = HediffDefOf.Bite; hediff_MissingPart.IsFresh = true; eatTarget.health.AddHediff(hediff_MissingPart, null, null); if (eatTargetIsCorpse == false && eatTargetDied == false && eatTarget.Dead) { Tools.DoWithAllZombies(map, z => { if (z.jobs != null) { var driver = z.jobs.curDriver as JobDriver_Stumble; if (driver != null && driver.eatTarget == eatTarget) { driver.eatTargetDied = true; driver.eatTargetIsCorpse = true; } } }); if (PawnUtility.ShouldSendNotificationAbout(eatTarget) && eatTarget.RaceProps.Humanlike) { Messages.Message("MessageEatenByPredator".Translate(new object[] { eatTarget.LabelShort, zombie.LabelIndefinite() }).CapitalizeFirst(), zombie, MessageSound.Negative); } eatTarget.Strip(); } return; } else { var corpse = map.thingGrid .ThingsListAt(eatTarget.Position) .OfType <Corpse>() .FirstOrDefault(c => c.InnerPawn == eatTarget); if (corpse != null) { corpse.Destroy(DestroyMode.Vanish); } Tools.DoWithAllZombies(map, z => { if (z.jobs != null) { var driver = z.jobs.curDriver as JobDriver_Stumble; if (driver != null && driver.eatTarget == eatTarget) { driver.eatTarget = null; driver.lastEatTarget = null; driver.eatDelayCounter = 0; } } }); } } else { var zombieLeaner = zombie.Drawer.leaner as ZombieLeaner; if (zombieLeaner != null) { zombieLeaner.extraOffset = Vector3.zero; } } var basePos = zombie.Position; // calculate possible moves, sort by pheromone value and take top 3 // then choose the one with the lowest zombie count // also, emit a circle of timestamps when discovering a pheromone // trace so nearby zombies pick it up too (leads to a chain reaction) // var grid = zombie.Map.GetGrid(); var possibleTrackingMoves = new List <IntVec3>(); var currentTicks = Tools.Ticks(); var timeDelta = long.MaxValue; for (int i = 0; i < 8; i++) { var pos = basePos + GenAdj.AdjacentCells[i]; if (currentTicks - grid.Get(pos, false).timestamp < fadeOff && zombie.HasValidDestination(pos)) { possibleTrackingMoves.Add(pos); } } if (possibleTrackingMoves.Count > 0) { possibleTrackingMoves.Sort((p1, p2) => SortByTimestamp(grid, p1, p2)); possibleTrackingMoves = possibleTrackingMoves.Take(Constants.NUMBER_OF_TOP_MOVEMENT_PICKS).ToList(); possibleTrackingMoves = possibleTrackingMoves.OrderBy(p => grid.Get(p, false).zombieCount).ToList(); var nextMove = possibleTrackingMoves.First(); timeDelta = currentTicks - grid.Get(nextMove, false).timestamp; destination = nextMove; if (zombie.state == ZombieState.Wandering) { Tools.ChainReact(zombie.Map, basePos, nextMove); if (timeDelta <= agitatedFadeoff) { CastBrainzThought(); } } zombie.state = ZombieState.Tracking; } if (destination.IsValid == false) { zombie.state = ZombieState.Wandering; } bool checkSmashable = timeDelta >= checkSmashableFadeoff; if (ZombieSettings.Values.smashOnlyWhenAgitated) { checkSmashable &= zombie.state == ZombieState.Tracking; } if (destination.IsValid == false || checkSmashable) { var building = CanSmash(); if (building != null) { destination = building.Position; if (Constants.USE_SOUND) { var info = SoundInfo.InMap(enemy); SoundDef.Named("ZombieHit").PlayOneShot(info); } AttackThing(building, JobDefOf.AttackStatic); return; } } if (destination.IsValid == false) { var hour = GenLocalDate.HourOfDay(Find.VisibleMap); // check for day/night and dust/dawn // var moveTowardsCenter = false; if (map.areaManager.Home[basePos] == false) { if (hour < 12) { hour += 24; } if (hour > Constants.HOUR_START_OF_NIGHT && hour < Constants.HOUR_END_OF_NIGHT) { moveTowardsCenter = true; } else if (hour >= Constants.HOUR_START_OF_DUSK && hour <= Constants.HOUR_START_OF_NIGHT) { moveTowardsCenter = Rand.RangeInclusive(hour, Constants.HOUR_START_OF_NIGHT) == Constants.HOUR_START_OF_NIGHT; } else if (hour >= Constants.HOUR_END_OF_NIGHT && hour <= Constants.HOUR_START_OF_DAWN) { moveTowardsCenter = Rand.RangeInclusive(Constants.HOUR_END_OF_NIGHT, hour) == Constants.HOUR_END_OF_NIGHT; } } var possibleMoves = new List <IntVec3>(); for (int i = 0; i < 8; i++) { var pos = basePos + GenAdj.AdjacentCells[i]; if (zombie.HasValidDestination(pos)) { possibleMoves.Add(pos); } } if (possibleMoves.Count > 0) { // during night, zombies drift towards the colonies center // if (moveTowardsCenter) { var center = zombie.wanderDestination.IsValid ? zombie.wanderDestination : map.Center; possibleMoves.Sort((p1, p2) => SortByDirection(center, p1, p2)); possibleMoves = possibleMoves.Take(Constants.NUMBER_OF_TOP_MOVEMENT_PICKS).ToList(); possibleMoves = possibleMoves.OrderBy(p => grid.Get(p, false).zombieCount).ToList(); destination = possibleMoves.First(); } else { // otherwise they sometimes stand or walk towards a random direction // if (Rand.Chance(Constants.STANDING_STILL_CHANCE)) { var n = possibleMoves.Count(); destination = possibleMoves[Constants.random.Next(n)]; } } } } // if we have a valid destination, go there // if (destination.IsValid) { MoveToCell(destination); } }
public override void Tick() { // Something has gone horribly wrong if (pawn.health.hediffSet.HasHediff(HediffDef.Named("PostPregnancy"))) { Log.Error("HumanPregnancy Hediff was not properly removed when pawn " + pawn.NameStringShort + " gave birth."); // delet this if (pawn.health.hediffSet.HasHediff(HediffDef.Named("GivingBirth"))) { pawn.health.RemoveHediff(pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth"))); } pawn.health.RemoveHediff(this); } this.ageTicks++; if (this.pawn.IsHashIntervalTick(1000)) { if (this.pawn.needs.food != null && this.pawn.needs.food.CurCategory == HungerCategory.Starving && Rand.MTBEventOccurs(0.5f, TicksPerDay, MiscarryCheckInterval)) { if (this.Visible && PawnUtility.ShouldSendNotificationAbout(this.pawn)) { Messages.Message("MessageMiscarriedStarvation".Translate(new object[] { this.pawn.LabelIndefinite() }).CapitalizeFirst(), this.pawn, MessageTypeDefOf.NegativeHealthEvent); } Miscarry(false); return; } if (this.IsSeverelyWounded && Rand.MTBEventOccurs(0.5f, TicksPerDay, MiscarryCheckInterval)) { if (this.Visible && PawnUtility.ShouldSendNotificationAbout(this.pawn)) { Messages.Message("MessageMiscarriedPoorHealth".Translate(new object[] { this.pawn.LabelIndefinite() }).CapitalizeFirst(), this.pawn, MessageTypeDefOf.NegativeHealthEvent); } Miscarry(false); return; } } GestationProgress += (1.0f) / (pawn.RaceProps.gestationPeriodDays * TicksPerDay); // Check if pregnancy is far enough along to "show" for the body type if (!is_discovered) { if ( (pawn.story.bodyType == BodyType.Female && GestationProgress > 0.389f) || (pawn.story.bodyType == BodyType.Thin && GestationProgress > 0.375f) || ((pawn.story.bodyType == BodyType.Fat || pawn.story.bodyType == BodyType.Hulk) && GestationProgress > 0.50f)) { // Got the numbers by dividing the average show time (in weeks) per body type by 36 // (36 weeks being the real human gestation period) // https://www.momtricks.com/pregnancy/when-do-you-start-showing-in-pregnancy/ DiscoverPregnancy(); } } // Final stage of pregnancy if (CurStageIndex == 3) { if (!pawn.health.hediffSet.HasHediff(HediffDef.Named("GivingBirth"))) { // Notify the player birth is near if (Visible && PawnUtility.ShouldSendNotificationAbout(pawn)) { Messages.Message("MessageHavingContractions".Translate(new object[] { pawn.LabelIndefinite() }).CapitalizeFirst(), pawn, MessageTypeDefOf.NeutralEvent); } // Give the mother the GivingBirth hediff pawn.health.AddHediff(HediffDef.Named("GivingBirth"), ChildrenUtility.GetPawnBodyPart(pawn, "Torso"), null); } // We're having contractions now else { // Has the pregnancy been tended to? if (pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth")).IsTended()) { // Then we get a safe pregnancy DoBirthSpawn(pawn, father, 1); } // natural birth (probably not a good idea!) else if (GestationProgress >= 1) { // Do risky pregnancy DoBirthSpawn(pawn, father, 0.9f); if (Rand.Value <= 0.1f) { pawn.health.AddHediff(HediffDef.Named("PlacentaBleed"), ChildrenUtility.GetPawnBodyPart(pawn, "Torso"), null); } } } } /*if (this.GestationProgress >= 1) { * if (this.Visible && PawnUtility.ShouldSendNotificationAbout (this.pawn)) { * Messages.Message ("MessageGaveBirth".Translate (new object[] { * this.pawn.LabelIndefinite () * }).CapitalizeFirst (), this.pawn, MessageSound.Benefit); * } * Hediff_Pregnant.DoBirthSpawn (this.pawn, this.father); * }*/ }
/* * public float SuccessChance(Pawn initiator, Pawn recipient) * { * float recipientAttraction = recipient.relations.SecondaryRomanceChanceFactor(initiator); * return 1f; * } */ // //allDefsListForReading.TryRandomElementByWeight((InteractionDef x) => x.Worker.RandomSelectionWeight(this.pawn, p), out intDef) public override void Interacted(Pawn initiator, Pawn recipient, List <RulePackDef> extraSentencePacks, out string letterText, out string letterLabel, out LetterDef letterDef) { if (lastInitiator != initiator || lastRecipient != recipient) { EmptyReasons(); recipientPhysicalAttraction = CalculateAndSort(AttractionFactorCategoryDefOf.Physical, initiator, recipient); recipientRomanticAttraction = CalculateAndSort(AttractionFactorCategoryDefOf.Romantic, initiator, recipient); recipientSocialAttraction = CalculateAndSort(AttractionFactorCategoryDefOf.Social, initiator, recipient); initiatorCircumstances = CalculateAndSort(AttractionFactorCategoryDefOf.Circumstance, initiator, recipient); } AttractionFactorDef whoCares; /* * initiatorPhysicalAttraction = CalculateAndSort(AttractionFactorCategoryDefOf.Physical, recipient, initiator, false); * initiatorRomanticAttraction = CalculateAndSort(AttractionFactorCategoryDefOf.Romantic, recipient, initiator, false); * initiatorSocialAttraction = CalculateAndSort(AttractionFactorCategoryDefOf.Social, recipient, initiator, false); * recipientCircumstances = CalculateAndSort(AttractionFactorCategoryDefOf.Circumstance, recipient, initiator, false); */ recipientCircumstances = AttractionUtility.CalculateAttractionCategory(AttractionFactorCategoryDefOf.Circumstance, recipient, initiator); float totalAttraction = AttractionUtility.CalculateAttraction(recipient, initiator, false, false, out veryLowRecipientReasons, out lowRecipientReasons, out highRecipientReasons, out veryHighRecipientReasons, out whoCares); initiatorPhysicalAttraction = GRHelper.GRPawnComp(recipient).RetrieveAttractionForCategory(initiator, AttractionFactorCategoryDefOf.Physical); initiatorRomanticAttraction = GRHelper.GRPawnComp(recipient).RetrieveAttractionForCategory(initiator, AttractionFactorCategoryDefOf.Romantic); initiatorSocialAttraction = GRHelper.GRPawnComp(recipient).RetrieveAttractionForCategory(initiator, AttractionFactorCategoryDefOf.Social); LogFlirt(initiator.Name.ToStringShort + "=>" + recipient.Name.ToStringShort + " attraction: physical " + recipientPhysicalAttraction.ToString() + ", romantic " + recipientRomanticAttraction.ToString() + ", social " + recipientSocialAttraction.ToString() + "."); List <FlirtStyleDef> allDefsListForReading = DefDatabase <FlirtStyleDef> .AllDefsListForReading; FlirtStyleDef flirtStyle; pressureCache = AttractionUtility.RelationshipStress(initiator, recipient); allDefsListForReading.TryRandomElementByWeight((FlirtStyleDef x) => CalculateFlirtStyleWeight(x, initiator, recipient), out flirtStyle); if (flirtStyle == null) { Log.Error("FailedToFindFlirt_error".Translate()); letterText = null; letterLabel = null; letterDef = null; return; } if (veryHighInitiatorReasons.Count() > 0) { AttractionFactorDef reason = veryHighInitiatorReasons.RandomElement <AttractionFactorDef>(); extraSentencePacks.Add(reason.intriguedByText); } else if (highInitiatorReasons.Count() > 0) { AttractionFactorDef reason = highInitiatorReasons.RandomElement <AttractionFactorDef>(); extraSentencePacks.Add(reason.intriguedByText); } if (recipient.gender == Gender.Male) { extraSentencePacks.Add(flirtStyle.rulePackMale); } if (recipient.gender == Gender.Female) { extraSentencePacks.Add(flirtStyle.rulePackFemale); } LogFlirt("Flirt chosen: " + flirtStyle.defName + "."); LogFlirt(recipient.Name.ToStringShort + "=>" + initiator.Name.ToStringShort + " attraction: physical " + initiatorPhysicalAttraction.ToString() + ", romantic " + initiatorRomanticAttraction.ToString() + ", social " + initiatorSocialAttraction.ToString() + "."); if (initiatorPhysicalAttraction == 0f || initiatorRomanticAttraction == 0f || initiatorSocialAttraction == 0f) { successImpossible = true; } else { successImpossible = false; } FlirtReactionDef flirtReaction = null; IEnumerable <FlirtReactionDef> successfulFlirtReactions = (from reaction in DefDatabase <FlirtReactionDef> .AllDefsListForReading where reaction.successful select reaction); IEnumerable <FlirtReactionDef> unsuccessfulFlirtReactions = (from reaction in DefDatabase <FlirtReactionDef> .AllDefsListForReading where !reaction.successful select reaction); List <FlirtReactionDef> allFlirtReactions = DefDatabase <FlirtReactionDef> .AllDefsListForReading; FlirtReactionDef successfulFlirt; FlirtReactionDef unsuccessfulFlirt; successfulFlirtReactions.TryRandomElementByWeight((FlirtReactionDef x) => CalculateFlirtReactionWeight(flirtStyle, x, initiator, recipient), out successfulFlirt); unsuccessfulFlirtReactions.TryRandomElementByWeight((FlirtReactionDef x) => CalculateFlirtReactionWeight(flirtStyle, x, initiator, recipient), out unsuccessfulFlirt); if (successImpossible) { flirtReaction = unsuccessfulFlirt; } else { //revise to include flirt type float chance = Mathf.Clamp01(GradualRomanceMod.RomanticSuccessRate * Mathf.Pow(initiatorPhysicalAttraction, flirtStyle.baseSexiness) * Mathf.Pow(initiatorRomanticAttraction, flirtStyle.baseRomance) * Mathf.Pow(initiatorSocialAttraction, flirtStyle.baseLogic) * recipientCircumstances * 0.65f); Log.Message("Romance success chance: " + chance.ToString()); if (Rand.Value < chance) { flirtReaction = successfulFlirt; } else { flirtReaction = unsuccessfulFlirt; } LogFlirt(recipient.Name.ToStringShort + " chose reaction " + flirtReaction.defName + " from Successful: " + successfulFlirt.defName + "; Unsuccessful: " + unsuccessfulFlirt.defName + "."); } if (flirtReaction == null) { Log.Error("FailedToFindReaction_error".Translate()); letterText = null; letterLabel = null; letterDef = null; return; } if (initiator.gender == Gender.Male) { extraSentencePacks.Add(flirtReaction.maleRulePack); } if (initiator.gender == Gender.Female) { extraSentencePacks.Add(flirtReaction.femaleRulePack); } if (flirtReaction != FlirtReactionDefOf.Ignorant) { if (flirtReaction.successful) { if (veryHighRecipientReasons.Count() > 0) { AttractionFactorDef reason = veryHighRecipientReasons.RandomElement <AttractionFactorDef>(); extraSentencePacks.Add(reason.reactionPositiveText); } else if (highRecipientReasons.Count() > 0) { AttractionFactorDef reason = highRecipientReasons.RandomElement <AttractionFactorDef>(); extraSentencePacks.Add(reason.reactionPositiveText); } } else { if (veryLowRecipientReasons.Count() > 0) { AttractionFactorDef reason = veryLowRecipientReasons.RandomElement <AttractionFactorDef>(); extraSentencePacks.Add(reason.reactionNegativeText); } else if (lowRecipientReasons.Count() > 0) { AttractionFactorDef reason = lowRecipientReasons.RandomElement <AttractionFactorDef>(); extraSentencePacks.Add(reason.reactionNegativeText); } } } flirtReaction.worker.GiveThoughts(initiator, recipient, out List <RulePackDef> yetMoreSentencePacks); extraSentencePacks.AddRange(yetMoreSentencePacks); letterText = null; letterLabel = null; letterDef = null; List <Pawn> loversInSight = RelationshipUtility.PotentiallyJealousPawnsInLineOfSight(initiator); List <Pawn> loversInSight2 = RelationshipUtility.PotentiallyJealousPawnsInLineOfSight(recipient); for (int i = 0; i < loversInSight.Count(); i++) { if (BreakupUtility.ShouldBeJealous(loversInSight[i], initiator, recipient)) { loversInSight[i].needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfGR.CaughtFlirting, initiator); if (flirtReaction.successful) { loversInSight[i].needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfGR.CaughtFlirtingWithLover, recipient); } } } if (flirtReaction.successful) { if (flirtReaction.provokesJealousy) { for (int i = 0; i < loversInSight2.Count(); i++) { if (BreakupUtility.ShouldBeJealous(loversInSight2[i], initiator, recipient)) { loversInSight2[i].needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfGR.CaughtFlirting, recipient); loversInSight2[i].needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfGR.CaughtFlirtingWithLover, initiator); } } } RelationshipUtility.AdvanceInformalRelationship(initiator, recipient, out PawnRelationDef newRelation, (flirtStyle.baseSweetheartChance * flirtReaction.sweetheartModifier)); if (newRelation != null && (PawnUtility.ShouldSendNotificationAbout(initiator) || PawnUtility.ShouldSendNotificationAbout(recipient))) { string initiatorParagraph = AttractionUtility.WriteReasonsParagraph(initiator, recipient, veryHighInitiatorReasons, highInitiatorReasons, lowInitiatorReasons, veryLowInitiatorReasons); string recipientParagraph = AttractionUtility.WriteReasonsParagraph(recipient, initiator, veryHighRecipientReasons, highRecipientReasons, lowRecipientReasons, veryLowRecipientReasons); letterDef = LetterDefOf.PositiveEvent; letterLabel = newRelation.GetModExtension <RomanticRelationExtension>().newRelationshipTitleText.Translate(); letterText = newRelation.GetModExtension <RomanticRelationExtension>().newRelationshipLetterText.Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2")); letterText += initiatorParagraph; letterText += recipientParagraph; /* if (newRelation == PawnRelationDefOfGR.Sweetheart) * { * letterDef = LetterDefOf.PositiveEvent; * letterLabel = "NewSweetheartsLabel".Translate(); * letterText = "NewSweetheartsText".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2")); * } * if (newRelation == PawnRelationDefOfGR.Lovebuddy) * { * letterDef = LetterDefOf.PositiveEvent; * letterLabel = "NewLovebuddiesLabel".Translate(); * letterText = "NewLovebuddiesText".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2")); * } * if (newRelation == PawnRelationDefOfGR.Paramour) * { * if (RelationshipUtility.IsAnAffair(initiator, recipient, out Pawn initiatorSO, out Pawn recipientSO)) * { * letterDef = LetterDefOf.NegativeEvent; * letterLabel = "ParamoursAffairLabel".Translate(); * if (initiatorSO != null && recipientSO != null) * { * letterText = "ParamoursAffairTwoCuckoldsText".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2"), initiatorSO.Named("CUCKOLD1"), recipientSO.Named("CUCKOLD2")); * } * if (initiatorSO != null && recipientSO == null) * { * letterText = "ParamoursAffairInitiatorCuckoldText".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2"), initiatorSO.Named("CUCKOLD1")); * } * if (initiatorSO == null && recipientSO != null) * { * letterText = "ParamoursAffairRecipientCuckoldText".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2"), recipientSO.Named("CUCKOLD1")); * } * } * else * { * letterDef = LetterDefOf.PositiveEvent; * letterLabel = "NewParamoursLabel".Translate(); * letterText = "NewParamoursText".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2")); * } * }*/ } } }
public void HealthTick() { if (this.Dead) { return; } for (int i = this.hediffSet.hediffs.Count - 1; i >= 0; i--) { Hediff hediff = this.hediffSet.hediffs[i]; try { hediff.Tick(); hediff.PostTick(); } catch (Exception ex) { Log.Error(string.Concat(new object[] { "Exception ticking hediff ", hediff.ToStringSafe <Hediff>(), " for pawn ", this.pawn.ToStringSafe <Pawn>(), ". Removing hediff... Exception: ", ex }), false); try { this.RemoveHediff(hediff); } catch (Exception arg) { Log.Error("Error while removing hediff: " + arg, false); } } } bool flag = false; for (int j = this.hediffSet.hediffs.Count - 1; j >= 0; j--) { Hediff hediff2 = this.hediffSet.hediffs[j]; if (hediff2.ShouldRemove) { this.hediffSet.hediffs.RemoveAt(j); hediff2.PostRemoved(); flag = true; } } if (flag) { this.Notify_HediffChanged(null); } if (this.Dead) { return; } this.immunity.ImmunityHandlerTick(); if (this.pawn.RaceProps.IsFlesh && this.pawn.IsHashIntervalTick(600) && (this.pawn.needs.food == null || !this.pawn.needs.food.Starving)) { bool flag2 = false; if (this.hediffSet.HasNaturallyHealingInjury()) { float num = 8f; if (this.pawn.GetPosture() != PawnPosture.Standing) { num += 4f; Building_Bed building_Bed = this.pawn.CurrentBed(); if (building_Bed != null) { num += building_Bed.def.building.bed_healPerDay; } } Hediff_Injury hediff_Injury = this.hediffSet.GetHediffs <Hediff_Injury>().Where(new Func <Hediff_Injury, bool>(HediffUtility.CanHealNaturally)).RandomElement <Hediff_Injury>(); hediff_Injury.Heal(num * this.pawn.HealthScale * 0.01f); flag2 = true; } if (this.hediffSet.HasTendedAndHealingInjury() && (this.pawn.needs.food == null || !this.pawn.needs.food.Starving)) { Hediff_Injury hediff_Injury2 = this.hediffSet.GetHediffs <Hediff_Injury>().Where(new Func <Hediff_Injury, bool>(HediffUtility.CanHealFromTending)).RandomElement <Hediff_Injury>(); float tendQuality = hediff_Injury2.TryGetComp <HediffComp_TendDuration>().tendQuality; float num2 = GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality)); hediff_Injury2.Heal(8f * num2 * this.pawn.HealthScale * 0.01f); flag2 = true; } if (flag2 && !this.HasHediffsNeedingTendByPlayer(false) && !HealthAIUtility.ShouldSeekMedicalRest(this.pawn) && !this.hediffSet.HasTendedAndHealingInjury() && PawnUtility.ShouldSendNotificationAbout(this.pawn)) { Messages.Message("MessageFullyHealed".Translate(this.pawn.LabelCap, this.pawn), this.pawn, MessageTypeDefOf.PositiveEvent, true); } } if (this.pawn.RaceProps.IsFlesh && this.hediffSet.BleedRateTotal >= 0.1f) { float num3 = this.hediffSet.BleedRateTotal * this.pawn.BodySize; if (this.pawn.GetPosture() == PawnPosture.Standing) { num3 *= 0.004f; } else { num3 *= 0.0004f; } if (Rand.Value < num3) { this.DropBloodFilth(); } } if (this.pawn.IsHashIntervalTick(60)) { List <HediffGiverSetDef> hediffGiverSets = this.pawn.RaceProps.hediffGiverSets; if (hediffGiverSets != null) { for (int k = 0; k < hediffGiverSets.Count; k++) { List <HediffGiver> hediffGivers = hediffGiverSets[k].hediffGivers; for (int l = 0; l < hediffGivers.Count; l++) { hediffGivers[l].OnIntervalPassed(this.pawn, null); if (this.pawn.Dead) { return; } } } } if (this.pawn.story != null) { List <Trait> allTraits = this.pawn.story.traits.allTraits; for (int m = 0; m < allTraits.Count; m++) { TraitDegreeData currentData = allTraits[m].CurrentData; if (currentData.randomDiseaseMtbDays > 0f && Rand.MTBEventOccurs(currentData.randomDiseaseMtbDays, 60000f, 60f)) { BiomeDef biome; if (this.pawn.Tile != -1) { biome = Find.WorldGrid[this.pawn.Tile].biome; } else { biome = DefDatabase <BiomeDef> .GetRandom(); } IncidentDef incidentDef = (from d in DefDatabase <IncidentDef> .AllDefs where d.category == IncidentCategoryDefOf.DiseaseHuman select d).RandomElementByWeightWithFallback((IncidentDef d) => biome.CommonalityOfDisease(d), null); if (incidentDef != null) { string text; List <Pawn> list = ((IncidentWorker_Disease)incidentDef.Worker).ApplyToPawns(Gen.YieldSingle <Pawn>(this.pawn), out text); if (PawnUtility.ShouldSendNotificationAbout(this.pawn)) { if (list.Contains(this.pawn)) { Find.LetterStack.ReceiveLetter("LetterLabelTraitDisease".Translate(incidentDef.diseaseIncident.label), "LetterTraitDisease".Translate(this.pawn.LabelCap, incidentDef.diseaseIncident.label, this.pawn.Named("PAWN")).AdjustedFor(this.pawn, "PAWN"), LetterDefOf.NegativeEvent, this.pawn, null, null); } else if (!text.NullOrEmpty()) { Messages.Message(text, this.pawn, MessageTypeDefOf.NeutralEvent, true); } } } } } } } }
public override void Interacted(Pawn initiator, Pawn recipient, List <RulePackDef> extraSentencePacks, out string letterText, out string letterLabel, out LetterDef letterDef) { ///Stitched in from Psychology. Thought thought = this.RandomBreakupReason(initiator, recipient); PawnRelationDef relation = GRPawnRelationUtility.MostAdvancedRelationshipBetween(initiator, recipient); if (initiator.relations.DirectRelationExists(PawnRelationDefOf.Spouse, recipient)) { BreakupUtility.RelationToEx(initiator, recipient, PawnRelationDefOf.Spouse); recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.DivorcedMe, initiator); recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfPsychology.BrokeUpWithMeCodependent, initiator); initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.GotMarried); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.GotMarried); initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.HoneymoonPhase, recipient); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.HoneymoonPhase, initiator); } else { BreakupUtility.ResolveBreakup(initiator, recipient, GRPawnRelationUtility.MostAdvancedRelationshipBetween(initiator, recipient)); } if (initiator.ownership.OwnedBed != null && initiator.ownership.OwnedBed == recipient.ownership.OwnedBed) { Pawn pawn = (Rand.Value >= 0.5f) ? recipient : initiator; pawn.ownership.UnclaimBed(); } TaleRecorder.RecordTale(TaleDefOf.Breakup, new object[] { initiator, recipient }); StringBuilder stringBuilder = new StringBuilder(); if (GRPawnRelationUtility.IsInformalRelationship(relation)) { stringBuilder.AppendLine("LetterInformalRelationsEnds".Translate(initiator.Named("PAWN1"), recipient.Named("PAWN2"))); letterDef = LetterDefOf.NeutralEvent; letterLabel = "LetterLabelInformalRelationsEnds".Translate(); } else { stringBuilder.AppendLine("LetterNoLongerLovers".Translate(initiator.LabelShort, recipient.LabelShort, initiator.Named("PAWN1"), recipient.Named("PAWN2"))); letterDef = LetterDefOf.NegativeEvent; letterLabel = "LetterLabelBreakup".Translate(); } if (thought != null) { stringBuilder.AppendLine(); stringBuilder.AppendLine("FinalStraw".Translate(thought.CurStage.label.CapitalizeFirst())); } if (PawnUtility.ShouldSendNotificationAbout(initiator) || PawnUtility.ShouldSendNotificationAbout(recipient)) { letterDef = null; letterLabel = null; letterText = null; } else if (GRPawnRelationUtility.IsInformalRelationship(relation) && GradualRomanceMod.informalRomanceLetters == false) { letterDef = null; letterLabel = null; letterText = null; } else { letterText = stringBuilder.ToString(); } }
private static bool on_begin_DoBirthSpawn(ref Pawn mother, ref Pawn father) { //TODO: Set pregnant hediff to torso //--Log.Message("patches_pregnancy::PATCH_Hediff_Pregnant::DoBirthSpawn() called"); var mother_name = (mother != null) ? mother.NameStringShort : "NULL"; var father_name = (father != null) ? father.NameStringShort : "NULL"; if (mother == null) { Log.Error("Hediff_Pregnant::DoBirthSpawn() - no mother defined"); return(false); } if (father == null) { Log.Warning("Hediff_Pregnant::DoBirthSpawn() - no father defined"); } // get a reference to the hediff we are applying Hediff_Pregnant self = (Hediff_Pregnant)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("Pregnant")); // determine litter size int litter_size = (mother.RaceProps.litterSizeCurve == null) ? 1 : Mathf.RoundToInt(Rand.ByCurve(mother.RaceProps.litterSizeCurve, 300)); if (litter_size < 1) { litter_size = 1; } float skin_whiteness = Rand.Range(0, 1); string last_name = null; // send a message about giving birth ////--Log.Message("Hediff_Pregnancy::DoBirthSpawn( " + mother_name + ", " + father_name + ", " + chance_successful + " ) - generating baby pawns"); if (self.Visible && PawnUtility.ShouldSendNotificationAbout(mother)) { Messages.Message("GivingBirth".Translate(new object[] { mother.LabelIndefinite() }).CapitalizeFirst(), mother, MessageTypeDefOf.NeutralEvent); } ////--Log.Message("Hediff_Pregnancy::DoBirthSpawn( " + mother_name + ", " + father_name + ", " + chance_successful + " ) - creating spawn request"); List <Pawn> siblings = new List <Pawn>(); for (int i = 0; i < litter_size; i++) { Pawn spawn_parent = mother; if (father != null && Mod_Settings.pregnancy_use_parent_method && (100 * Rand.Value) > Mod_Settings.pregnancy_weight_parent) { spawn_parent = father; } PawnGenerationRequest request = new PawnGenerationRequest(spawn_parent.kindDef, spawn_parent.Faction, PawnGenerationContext.NonPlayer, spawn_parent.Map.Tile, false, true, false, false, false, false, 1, false, true, true, false, false, false, false, null, null, 0, 0, null, skin_whiteness, last_name); ////--Log.Message("Hediff_GenericPregnancy::DoBirthSpawn( " + mother_name + ", " + father_name + ", " + chance_successful + " ) - spawning baby"); Pawn baby = PawnGenerator.GeneratePawn(request); if (PawnUtility.TrySpawnHatchedOrBornPawn(baby, mother)) { if (baby.playerSettings != null && mother.playerSettings != null) { baby.playerSettings.AreaRestriction = mother.playerSettings.AreaRestriction; } if (baby.RaceProps.IsFlesh) { baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, mother); if (father != null) { baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, father); } foreach (Pawn sibling in siblings) { baby.relations.AddDirectRelation(PawnRelationDefOf.Sibling, sibling); } siblings.Add(baby); //inject RJW_BabyState to the newborn if RimWorldChildren is not active if (!xxx.RimWorldChildrenIsActive && baby.kindDef.race == ThingDefOf.Human && baby.ageTracker.CurLifeStageIndex <= 1 && baby.ageTracker.AgeBiologicalYears < 1 && !baby.Dead) { // Clean out drug randomly generated drug addictions baby.health.hediffSet.Clear(); baby.health.AddHediff(HediffDef.Named("RJW_BabyState"), null, null); Hediff_SimpleBaby babystate = (Hediff_SimpleBaby)baby.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("RJW_BabyState")); if (babystate != null) { babystate.GrowUpTo(0, true); } } } } else { Find.WorldPawns.PassToWorld(baby, PawnDiscardDecideMode.Discard); } } ////--Log.Message("Hediff_Pregnancy::DoBirthSpawn( " + mother_name + ", " + father_name + ", " + chance_successful + " ) - removing pregnancy"); mother.health.RemoveHediff(self); return(false); }
public override void Interacted(Pawn initiator, Pawn recipient, List <RulePackDef> extraSentencePacks, out string letterText, out string letterLabel, out LetterDef letterDef) { if (lastInitiator != initiator || lastRecipient != recipient) { AttractionUtility.CalculateAttraction(initiator, recipient, false, true, out veryLowInitiatorReasons, out lowInitiatorReasons, out highInitiatorReasons, out veryHighInitiatorReasons, out AttractionFactorDef reasonForInstantFailure); } if (Rand.Value < this.SuccessChance(initiator, recipient)) { List <Pawn> list; this.BreakLoverAndFianceRelations(initiator, out list); List <Pawn> list2; this.BreakLoverAndFianceRelations(recipient, out list2); for (int i = 0; i < list.Count; i++) { BreakupUtility.TryAddCheaterThought(list[i], initiator, recipient); } for (int j = 0; j < list2.Count; j++) { BreakupUtility.TryAddCheaterThought(list2[j], recipient, initiator); } initiator.relations.TryRemoveDirectRelation(PawnRelationDefOf.ExLover, recipient); initiator.relations.TryRemoveDirectRelation(PawnRelationDefOfGR.ExLovefriend, recipient); GRPawnRelationUtility.AdvanceRelationship(recipient, initiator, PawnRelationDefOfGR.Lovefriend); //TODO Change record tale TaleRecorder.RecordTale(TaleDefOf.BecameLover, new object[] { initiator, recipient }); initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.BrokeUpWithMe, recipient); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.BrokeUpWithMe, initiator); initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.FailedRomanceAttemptOnMe, recipient); initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.FailedRomanceAttemptOnMeLowOpinionMood, recipient); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.FailedRomanceAttemptOnMe, initiator); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.FailedRomanceAttemptOnMeLowOpinionMood, initiator); if (PawnUtility.ShouldSendNotificationAbout(initiator) || PawnUtility.ShouldSendNotificationAbout(recipient)) { this.GetNewLoversLetter(initiator, recipient, list, list2, out letterText, out letterLabel, out letterDef); letterText += AttractionUtility.WriteReasonsParagraph(initiator, recipient, veryHighInitiatorReasons, highInitiatorReasons, lowInitiatorReasons, veryLowInitiatorReasons); letterText += AttractionUtility.WriteReasonsParagraph(recipient, initiator, veryHighRecipientReasons, highRecipientReasons, lowRecipientReasons, veryLowRecipientReasons); } else { letterText = null; letterLabel = null; letterDef = null; } extraSentencePacks.Add(RulePackDefOf.Sentence_RomanceAttemptAccepted); } else { initiator.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.RebuffedMyRomanceAttempt, recipient); recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.FailedRomanceAttemptOnMe, initiator); if (recipient.relations.OpinionOf(initiator) <= 0) { recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.FailedRomanceAttemptOnMeLowOpinionMood, initiator); } extraSentencePacks.Add(RulePackDefOf.Sentence_RomanceAttemptRejected); letterText = null; letterLabel = null; letterDef = null; } }
public void HealthTick() { if (!this.Dead) { for (int num = this.hediffSet.hediffs.Count - 1; num >= 0; num--) { Hediff hediff = this.hediffSet.hediffs[num]; hediff.Tick(); hediff.PostTick(); } bool flag = false; for (int num2 = this.hediffSet.hediffs.Count - 1; num2 >= 0; num2--) { Hediff hediff2 = this.hediffSet.hediffs[num2]; if (hediff2.ShouldRemove) { this.hediffSet.hediffs.RemoveAt(num2); hediff2.PostRemoved(); flag = true; } } if (flag) { this.Notify_HediffChanged(null); } if (!this.Dead) { this.immunity.ImmunityHandlerTick(); if (this.pawn.RaceProps.IsFlesh && this.pawn.IsHashIntervalTick(600) && (this.pawn.needs.food == null || !this.pawn.needs.food.Starving)) { bool flag2 = false; if (this.hediffSet.HasNaturallyHealingInjury()) { float num3 = 8f; if (this.pawn.GetPosture() != 0) { num3 = (float)(num3 + 4.0); Building_Bed building_Bed = this.pawn.CurrentBed(); if (building_Bed != null) { num3 += building_Bed.def.building.bed_healPerDay; } } Hediff_Injury hediff_Injury = this.hediffSet.GetHediffs <Hediff_Injury>().Where(HediffUtility.CanHealNaturally).RandomElement(); hediff_Injury.Heal((float)(num3 * this.pawn.HealthScale * 0.0099999997764825821)); flag2 = true; } if (this.hediffSet.HasTendedAndHealingInjury() && (this.pawn.needs.food == null || !this.pawn.needs.food.Starving)) { Hediff_Injury hediff_Injury2 = this.hediffSet.GetHediffs <Hediff_Injury>().Where(HediffUtility.CanHealFromTending).RandomElement(); float tendQuality = hediff_Injury2.TryGetComp <HediffComp_TendDuration>().tendQuality; float num4 = GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality)); hediff_Injury2.Heal((float)(22.0 * num4 * this.pawn.HealthScale * 0.0099999997764825821)); flag2 = true; } if (flag2 && !this.HasHediffsNeedingTendByColony(false) && !HealthAIUtility.ShouldSeekMedicalRest(this.pawn) && !this.hediffSet.HasTendedAndHealingInjury() && PawnUtility.ShouldSendNotificationAbout(this.pawn)) { Messages.Message("MessageFullyHealed".Translate(this.pawn.LabelCap), this.pawn, MessageTypeDefOf.PositiveEvent); } } if (this.pawn.RaceProps.IsFlesh && this.hediffSet.BleedRateTotal >= 0.10000000149011612) { float num5 = this.hediffSet.BleedRateTotal * this.pawn.BodySize; num5 = (float)((this.pawn.GetPosture() != 0) ? (num5 * 0.00079999997979030013) : (num5 * 0.00800000037997961)); if (Rand.Value < num5) { this.TryDropBloodFilth(); } } List <HediffGiverSetDef> hediffGiverSets = this.pawn.RaceProps.hediffGiverSets; if (hediffGiverSets != null && this.pawn.IsHashIntervalTick(60)) { for (int i = 0; i < hediffGiverSets.Count; i++) { List <HediffGiver> hediffGivers = hediffGiverSets[i].hediffGivers; int num6 = 0; while (num6 < hediffGivers.Count) { hediffGivers[num6].OnIntervalPassed(this.pawn, null); if (!this.pawn.Dead) { num6++; continue; } return; } } } } } }
public static Toil DrinkTerrain(TargetIndex cellIndex, int baseDrinkTicksFromTerrain) { // 地形から水を飲む int initialTicks = 1; Toil toil = new Toil(); toil.initAction = delegate { var actor = toil.actor; var cell = actor.CurJob.GetTarget(cellIndex).Cell; var need_water = actor.needs.water(); if (need_water == null) { actor.jobs.EndCurrentJob(JobCondition.Incompletable); return; } var waterType = cell.GetTerrain(actor.Map).ToWaterType(); if (waterType == WaterType.NoWater || waterType == WaterType.Undefined) { actor.jobs.EndCurrentJob(JobCondition.Incompletable); return; } var waterTypeDef = MizuDef.Dic_WaterTypeDef[waterType]; // 向き変更 actor.rotationTracker.FaceCell(actor.Position); // 作業量 actor.jobs.curDriver.ticksLeftThisToil = (int)(baseDrinkTicksFromTerrain * need_water.WaterWanted); initialTicks = actor.jobs.curDriver.ticksLeftThisToil; if (actor.needs.mood != null) { // 水分摂取による心情変化 List <ThoughtDef> thoughtList = new List <ThoughtDef>(); MizuUtility.ThoughtsFromWaterTypeDef(actor, waterTypeDef, true, thoughtList); foreach (var thoughtDef in thoughtList) { actor.needs.mood.thoughts.memories.TryGainMemory(thoughtDef); } } // 指定された健康状態になる if (waterTypeDef.hediffs != null) { foreach (var hediff in waterTypeDef.hediffs) { actor.health.AddHediff(HediffMaker.MakeHediff(hediff, actor)); } } // 確率で食中毒 if (Rand.Value < waterTypeDef.foodPoisonChance) { actor.health.AddHediff(HediffMaker.MakeHediff(HediffDefOf.FoodPoisoning, actor)); if (PawnUtility.ShouldSendNotificationAbout(actor)) { Messages.Message("MessageFoodPoisoning".Translate(new object[] { actor.LabelShort, "AreaLower".Translate() }).CapitalizeFirst(), actor, MessageTypeDefOf.NegativeEvent); } } }; toil.tickAction = delegate { toil.actor.GainComfortFromCellIfPossible(); var need_water = toil.actor.needs.water(); var cell = toil.actor.CurJob.GetTarget(cellIndex).Cell; if (need_water == null) { toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable); return; } // 徐々に飲む float riseNeedWater = 1 / (float)baseDrinkTicksFromTerrain; need_water.CurLevel = Mathf.Min(need_water.CurLevel + riseNeedWater, need_water.MaxLevel); }; toil.WithProgressBar(cellIndex, delegate { return(1f - (float)toil.actor.jobs.curDriver.ticksLeftThisToil / initialTicks); }, false, -0.5f); toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.FailOn((t) => { Pawn actor = toil.actor; return(actor.CurJob.targetA.Cell.IsForbidden(actor) || !actor.CanReach(actor.CurJob.targetA.Cell, PathEndMode.OnCell, Danger.Deadly)); }); // エフェクト追加 toil.PlaySustainerOrSound(delegate { return(DefDatabase <SoundDef> .GetNamed("Ingest_Beer")); }); return(toil); }
public static bool NewInteracted(InteractionWorker_Breakup __instance, Pawn initiator, Pawn recipient, List <RulePackDef> extraSentencePacks) { /* If you want to patch this method, you can stuff it. */ Thought thought = __instance.RandomBreakupReason(initiator, recipient); if (initiator.relations.DirectRelationExists(PawnRelationDefOf.Spouse, recipient)) { initiator.relations.RemoveDirectRelation(PawnRelationDefOf.Spouse, recipient); initiator.relations.AddDirectRelation(PawnRelationDefOf.ExSpouse, recipient); recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.DivorcedMe, initiator); recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfPsychology.BrokeUpWithMeCodependent, initiator); initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.GotMarried); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.GotMarried); initiator.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.HoneymoonPhase, recipient); recipient.needs.mood.thoughts.memories.RemoveMemoriesOfDefWhereOtherPawnIs(ThoughtDefOf.HoneymoonPhase, initiator); } else { initiator.relations.TryRemoveDirectRelation(PawnRelationDefOf.Lover, recipient); initiator.relations.TryRemoveDirectRelation(PawnRelationDefOf.Fiance, recipient); PsychologyPawn realRecipient = recipient as PsychologyPawn; PsychologyPawn realInitiator = initiator as PsychologyPawn; if (realRecipient != null && realInitiator != null) { BreakupHelperMethods.AddExLover(realInitiator, realRecipient); //AddExLover(realRecipient, realInitiator); BreakupHelperMethods.AddBrokeUpOpinion(realRecipient, realInitiator); BreakupHelperMethods.AddBrokeUpMood(realRecipient, realInitiator); BreakupHelperMethods.AddBrokeUpMood(realInitiator, realRecipient); } else { initiator.relations.AddDirectRelation(PawnRelationDefOf.ExLover, recipient); recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.BrokeUpWithMe, initiator); recipient.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOfPsychology.BrokeUpWithMeCodependent, initiator); } } if (initiator.ownership.OwnedBed != null && initiator.ownership.OwnedBed == recipient.ownership.OwnedBed) { Pawn pawn = (Rand.Value >= 0.5f) ? recipient : initiator; pawn.ownership.UnclaimBed(); } TaleRecorder.RecordTale(TaleDefOf.Breakup, new object[] { initiator, recipient }); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("LetterNoLongerLovers".Translate(new object[] { initiator.LabelShort, recipient.LabelShort })); if (thought != null) { stringBuilder.AppendLine(); stringBuilder.AppendLine("FinalStraw".Translate(new object[] { thought.CurStage.label })); } if (PawnUtility.ShouldSendNotificationAbout(initiator) || PawnUtility.ShouldSendNotificationAbout(recipient)) { Find.LetterStack.ReceiveLetter("LetterLabelBreakup".Translate(), stringBuilder.ToString(), LetterDefOf.BadNonUrgent, initiator, null); } return(false); }
public virtual void Tick() { ageTicks++; if (def.hediffGivers != null && pawn.IsHashIntervalTick(60)) { for (int i = 0; i < def.hediffGivers.Count; i++) { def.hediffGivers[i].OnIntervalPassed(pawn, this); } } if (Visible && !visible) { visible = true; if (def.taleOnVisible != null) { TaleRecorder.RecordTale(def.taleOnVisible, pawn, def); } } HediffStage curStage = CurStage; if (curStage != null) { if (curStage.hediffGivers != null && pawn.IsHashIntervalTick(60)) { for (int j = 0; j < curStage.hediffGivers.Count; j++) { curStage.hediffGivers[j].OnIntervalPassed(pawn, this); } } if (curStage.mentalStateGivers != null && pawn.IsHashIntervalTick(60) && !pawn.InMentalState) { for (int k = 0; k < curStage.mentalStateGivers.Count; k++) { MentalStateGiver mentalStateGiver = curStage.mentalStateGivers[k]; if (Rand.MTBEventOccurs(mentalStateGiver.mtbDays, 60000f, 60f)) { pawn.mindState.mentalStateHandler.TryStartMentalState(mentalStateGiver.mentalState, "MentalStateReason_Hediff".Translate(Label)); } } } if (curStage.mentalBreakMtbDays > 0f && pawn.IsHashIntervalTick(60) && !pawn.InMentalState && Rand.MTBEventOccurs(curStage.mentalBreakMtbDays, 60000f, 60f) && (from x in DefDatabase <MentalBreakDef> .AllDefsListForReading where x.Worker.BreakCanOccur(pawn) select x).TryRandomElementByWeight((MentalBreakDef x) => x.Worker.CommonalityFor(pawn), out MentalBreakDef result)) { result.Worker.TryStart(pawn, "MentalStateReason_Hediff".Translate(Label), causedByMood: false); } if (curStage.vomitMtbDays > 0f && pawn.IsHashIntervalTick(600) && Rand.MTBEventOccurs(curStage.vomitMtbDays, 60000f, 600f) && pawn.Spawned && pawn.Awake()) { pawn.jobs.StartJob(new Job(JobDefOf.Vomit), JobCondition.InterruptForced, null, resumeCurJobAfterwards: true); } if (curStage.forgetMemoryThoughtMtbDays > 0f && pawn.needs.mood != null && pawn.IsHashIntervalTick(400) && Rand.MTBEventOccurs(curStage.forgetMemoryThoughtMtbDays, 60000f, 400f) && pawn.needs.mood.thoughts.memories.Memories.TryRandomElement(out Thought_Memory result2)) { pawn.needs.mood.thoughts.memories.RemoveMemory(result2); } if (!recordedTale && curStage.tale != null) { TaleRecorder.RecordTale(curStage.tale, pawn); recordedTale = true; } if (curStage.destroyPart && Part != null && Part != pawn.RaceProps.body.corePart) { pawn.health.AddHediff(HediffDefOf.MissingBodyPart, Part); } if (curStage.deathMtbDays > 0f && pawn.IsHashIntervalTick(200) && Rand.MTBEventOccurs(curStage.deathMtbDays, 60000f, 200f)) { bool flag = PawnUtility.ShouldSendNotificationAbout(pawn); Caravan caravan = pawn.GetCaravan(); pawn.Kill(null, null); if (flag) { pawn.health.NotifyPlayerOfKilled(null, this, caravan); } } } }
// Token: 0x06000016 RID: 22 RVA: 0x0000259C File Offset: 0x0000079C public static void DoSSVape(Pawn p, Thing t) { var HediffName = ""; var defName = t.def.defName; switch (defName) { case "SSVaperRegular": HediffName = "SSVape_Regular_High"; break; case "SSVaperFruity": HediffName = "SSVape_Fruity_High"; break; case "SSVaperMenthol": HediffName = "SSVape_Menthol_High"; break; } if (!HediffName.StartsWith("SSVape")) { return; } var hediffdef = DefDatabase <HediffDef> .GetNamed(HediffName, false); var SLChemDef = DefDatabase <ChemicalDef> .GetNamed("Smokeleaf"); if (hediffdef == null) { return; } var SeverityToApply = 0.5f; if (SSHediffEffecter.HediffEffect(hediffdef, SeverityToApply, p, null, out _)) { var SLTol = DefDatabase <HediffDef> .GetNamed("SmokeleafTolerance"); if (SLTol != null) { var Sev = 0.02f / p.BodySize; SSHediffEffecter.HediffEffect(SLTol, Sev, p, null, out _); } if (p.RaceProps.IsFlesh) { var addictionHediffDef = DefDatabase <HediffDef> .GetNamed("SmokeleafAddiction"); var hediff_Addiction = AddictionUtility.FindAddictionHediff(p, SLChemDef); var hediff = AddictionUtility.FindToleranceHediff(p, SLChemDef); var num = hediff?.Severity ?? 0f; if (hediff_Addiction != null) { hediff_Addiction.Severity += 0.06f; } else if (Rand.Value < 0.01f && num >= 0.15f) { p.health.AddHediff(addictionHediffDef); if (PawnUtility.ShouldSendNotificationAbout(p)) { Find.LetterStack.ReceiveLetter( "LetterLabelNewlyAddicted".Translate(SLChemDef.label).CapitalizeFirst(), "LetterNewlyAddicted".Translate(p.LabelShort, SLChemDef.label, p.Named("PAWN")) .AdjustedFor(p).CapitalizeFirst(), LetterDefOf.NegativeEvent, p); } } if (addictionHediffDef.causesNeed != null) { var need = p.needs.AllNeeds.Find(x => x.def == addictionHediffDef.causesNeed); if (need != null) { var effect = 1f; AddictionUtility.ModifyChemicalEffectForToleranceAndBodySize(p, SLChemDef, ref effect); need.CurLevel += effect; } } } } if (p?.needs != null) { var need2 = p.needs.TryGetNeed(NeedDefOf.Rest); if (need2 != null) { var effect2 = -0.1f; AddictionUtility.ModifyChemicalEffectForToleranceAndBodySize(p, SLChemDef, ref effect2); need2.CurLevel += effect2; } } bool joyNeed; if (p == null) { joyNeed = false; } else { var needs = p.needs; joyNeed = needs?.joy != null; } if (joyNeed) { var Chem = DefDatabase <JoyKindDef> .GetNamed("Chemical", false); var needs2 = p.needs; if (needs2 != null) { needs2.joy.GainJoy(0.85f, Chem); } } if (p?.Map != null) { var BreathOffset = new Vector3(0f, 0f, -0.04f); var loc = p.Drawer.DrawPos + p.Drawer.renderer.BaseHeadOffsetAt(p.Rotation) + (p.Rotation.FacingCell.ToVector3() * 0.21f) + BreathOffset; for (var i = 0; i < 4; i++) { ThrowVapeBreathPuff(loc, p.Map, p.Rotation.AsAngle, p.Position.ToVector3()); FleckMaker.ThrowSmoke(p.Position.ToVector3(), p.Map, 0.5f); } } var usesLeft = ((SSVapeData)t).SSVapeUses; usesLeft--; ((SSVapeData)t).SSVapeUses = usesLeft; if (usesLeft > 0) { return; } t.Destroy(); if (p == null) { return; } GenDrop.TryDropSpawn( ThingMaker.MakeThing(DefDatabase <ThingDef> .GetNamed("SSVaperEmpty", false)), p.Position, p.Map, ThingPlaceMode.Near, out var newVapeThing); ((SSVapeData)newVapeThing).SSVapeType = "empty"; ((SSVapeData)newVapeThing).SSVapeUses = 0; }
private void CheckDiscovered() { if (!this.discovered) { if (this.parent.CurStage.becomeVisible) { this.discovered = true; if (this.Props.sendLetterWhenDiscovered && PawnUtility.ShouldSendNotificationAbout(base.Pawn)) { if (base.Pawn.RaceProps.Humanlike) { string label; if (!this.Props.discoverLetterLabel.NullOrEmpty()) { label = string.Format(this.Props.discoverLetterLabel, base.Pawn.LabelShort.CapitalizeFirst()).CapitalizeFirst(); } else { label = "LetterLabelNewDisease".Translate() + " (" + base.Def.label + ")"; } string text; if (!this.Props.discoverLetterText.NullOrEmpty()) { text = string.Format(this.Props.discoverLetterText, base.Pawn.LabelIndefinite()).AdjustedFor(base.Pawn, "PAWN").CapitalizeFirst(); } else if (this.parent.Part == null) { text = "NewDisease".Translate(new object[] { base.Pawn.LabelIndefinite(), base.Def.label, base.Pawn.LabelDefinite() }).AdjustedFor(base.Pawn, "PAWN").CapitalizeFirst(); } else { text = "NewPartDisease".Translate(new object[] { base.Pawn.LabelIndefinite(), this.parent.Part.Label, base.Pawn.LabelDefinite(), base.Def.LabelCap }).AdjustedFor(base.Pawn, "PAWN").CapitalizeFirst(); } Find.LetterStack.ReceiveLetter(label, text, (this.Props.letterType == null) ? LetterDefOf.NegativeEvent : this.Props.letterType, base.Pawn, null, null); } else { string text2; if (!this.Props.discoverLetterText.NullOrEmpty()) { text2 = string.Format(this.Props.discoverLetterText, base.Pawn.LabelIndefinite()).AdjustedFor(base.Pawn, "PAWN").CapitalizeFirst(); } else if (this.parent.Part == null) { text2 = "NewDiseaseAnimal".Translate(new object[] { base.Pawn.LabelShort, base.Def.LabelCap, base.Pawn.LabelDefinite() }).AdjustedFor(base.Pawn, "PAWN").CapitalizeFirst(); } else { text2 = "NewPartDiseaseAnimal".Translate(new object[] { base.Pawn.LabelShort, this.parent.Part.Label, base.Pawn.LabelDefinite(), base.Def.LabelCap }).AdjustedFor(base.Pawn, "PAWN").CapitalizeFirst(); } Messages.Message(text2, base.Pawn, (this.Props.messageType == null) ? MessageTypeDefOf.NegativeHealthEvent : this.Props.messageType, true); } } } } }
public static bool TryGainMemory(MemoryThoughtHandler __instance, Thought_Memory newThought, Pawn otherPawn = null) { if (!ThoughtUtility.CanGetThought_NewTemp(__instance.pawn, newThought.def)) { return(false); } if (newThought is Thought_MemorySocial && newThought.otherPawn == null && otherPawn == null) { Log.Error(string.Concat("Can't gain social thought ", newThought.def, " because its otherPawn is null and otherPawn passed to this method is also null. Social thoughts must have otherPawn.")); return(false); } newThought.pawn = __instance.pawn; newThought.otherPawn = otherPawn; if (!newThought.TryMergeWithExistingMemory(out bool showBubble)) { lock (__instance) { List <Thought_Memory> newMemories = new List <Thought_Memory>(__instance.Memories) { newThought }; memoriesFieldRef(__instance) = newMemories; } } if (newThought.def.stackLimitForSameOtherPawn >= 0) { while (__instance.NumMemoriesInGroup(newThought) > newThought.def.stackLimitForSameOtherPawn) { __instance.RemoveMemory(__instance.OldestMemoryInGroup(newThought)); } } if (newThought.def.stackLimit >= 0) { while (__instance.NumMemoriesOfDef(newThought.def) > newThought.def.stackLimit) { __instance.RemoveMemory(__instance.OldestMemoryOfDef(newThought.def)); } } if (newThought.def.thoughtToMake != null) { __instance.TryGainMemory(newThought.def.thoughtToMake, newThought.otherPawn); } if (showBubble && newThought.def.showBubble && __instance.pawn.Spawned && PawnUtility.ShouldSendNotificationAbout(__instance.pawn)) { MoteMaker.MakeMoodThoughtBubble(__instance.pawn, newThought); } return(false); }
public virtual void Tick() { ageTicks++; if (def.hediffGivers != null && pawn.IsHashIntervalTick(60)) { for (int i = 0; i < def.hediffGivers.Count; i++) { def.hediffGivers[i].OnIntervalPassed(pawn, this); } } if (Visible && !visible) { visible = true; if (def.taleOnVisible != null) { TaleRecorder.RecordTale(def.taleOnVisible, pawn, def); } } HediffStage curStage = CurStage; if (curStage == null) { return; } if (curStage.hediffGivers != null && pawn.IsHashIntervalTick(60)) { for (int j = 0; j < curStage.hediffGivers.Count; j++) { curStage.hediffGivers[j].OnIntervalPassed(pawn, this); } } if (curStage.mentalStateGivers != null && pawn.IsHashIntervalTick(60) && !pawn.InMentalState) { for (int k = 0; k < curStage.mentalStateGivers.Count; k++) { MentalStateGiver mentalStateGiver = curStage.mentalStateGivers[k]; if (Rand.MTBEventOccurs(mentalStateGiver.mtbDays, 60000f, 60f)) { pawn.mindState.mentalStateHandler.TryStartMentalState(mentalStateGiver.mentalState, "MentalStateReason_Hediff".Translate(Label)); } } } if (curStage.mentalBreakMtbDays > 0f && pawn.IsHashIntervalTick(60) && !pawn.InMentalState && !pawn.Downed && Rand.MTBEventOccurs(curStage.mentalBreakMtbDays, 60000f, 60f)) { TryDoRandomMentalBreak(); } if (curStage.vomitMtbDays > 0f && pawn.IsHashIntervalTick(600) && Rand.MTBEventOccurs(curStage.vomitMtbDays, 60000f, 600f) && pawn.Spawned && pawn.Awake() && pawn.RaceProps.IsFlesh) { pawn.jobs.StartJob(JobMaker.MakeJob(JobDefOf.Vomit), JobCondition.InterruptForced, null, resumeCurJobAfterwards: true); } if (curStage.forgetMemoryThoughtMtbDays > 0f && pawn.needs != null && pawn.needs.mood != null && pawn.IsHashIntervalTick(400) && Rand.MTBEventOccurs(curStage.forgetMemoryThoughtMtbDays, 60000f, 400f) && pawn.needs.mood.thoughts.memories.Memories.TryRandomElement(out Thought_Memory result)) { pawn.needs.mood.thoughts.memories.RemoveMemory(result); } if (!recordedTale && curStage.tale != null) { TaleRecorder.RecordTale(curStage.tale, pawn); recordedTale = true; } if (curStage.destroyPart && Part != null && Part != pawn.RaceProps.body.corePart) { pawn.health.AddHediff(HediffDefOf.MissingBodyPart, Part); } if (curStage.deathMtbDays > 0f && pawn.IsHashIntervalTick(200) && Rand.MTBEventOccurs(curStage.deathMtbDays, 60000f, 200f)) { bool num = PawnUtility.ShouldSendNotificationAbout(pawn); Caravan caravan = pawn.GetCaravan(); pawn.Kill(null, null); if (num) { pawn.health.NotifyPlayerOfKilled(null, this, caravan); } } }
// // Methods // public void DoBirthSpawn(Pawn mother, Pawn father, float chance_successful = 1.0f) { if (mother == null) { Log.Error("No mother defined"); return; } if (father == null) { Log.Warning("No father defined"); } float birthing_quality = mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth")).TryGetComp <HediffComp_TendDuration> ().tendQuality; mother.health.AddHediff(HediffDef.Named("PostPregnancy"), null, null); mother.health.AddHediff(HediffDef.Named("Lactating"), ChildrenUtility.GetPawnBodyPart(pawn, "Torso"), null); int num = (mother.RaceProps.litterSizeCurve == null) ? 1 : Mathf.RoundToInt(Rand.ByCurve(mother.RaceProps.litterSizeCurve, 300)); if (num < 1) { num = 1; } // Make sure the pawn looks like mommy and daddy float skin_whiteness = Rand.Range(0, 1); // Pool of "genetic traits" the baby can inherit List <Trait> traitpool = new List <Trait>(); if (mother.RaceProps.Humanlike) { // Add mom's traits to the pool foreach (Trait momtrait in mother.story.traits.allTraits) { traitpool.Add(momtrait); } if (father != null) { // Add dad's traits to the pool foreach (Trait dadtrait in father.story.traits.allTraits) { traitpool.Add(dadtrait); } // Blend skin colour between mom and dad skin_whiteness = Rand.Range(mother.story.melanin, father.story.melanin); } else { // If dad doesn't exist, just use mom's skin colour skin_whiteness = mother.story.melanin; } // Clear out any traits that aren't genetic from the list if (traitpool.Count > 0) { foreach (Trait trait in traitpool.ToArray()) { bool is_genetic = false; foreach (TraitDef gentrait in genetic_traits) { if (gentrait.defName == trait.def.defName) { is_genetic = true; } } if (!is_genetic) { traitpool.Remove(trait); } } } } // Surname passing string last_name = null; if (mother.RaceProps.Humanlike) { if (father == null) { last_name = NameTriple.FromString(mother.Name.ToStringFull).Last; } else { last_name = NameTriple.FromString(father.Name.ToStringFull).Last; } //Log.Message ("Debug: Newborn is born to the " + last_name + " family."); } //PawnGenerationRequest request = new PawnGenerationRequest (mother.kindDef, mother.Faction, PawnGenerationContext.NonPlayer, mother.Map, false, true, false, false, true, false, 1, false, true, true, null, 0, 0, null, skin_whiteness, last_name); PawnGenerationRequest request = new PawnGenerationRequest(mother.kindDef, mother.Faction, PawnGenerationContext.NonPlayer, mother.Map.Tile, false, true, false, false, false, false, 1, false, true, true, false, false, null, 0, 0, null, skin_whiteness, last_name); Pawn baby = null; for (int i = 0; i < num; i++) { baby = PawnGenerator.GeneratePawn(request); if (PawnUtility.TrySpawnHatchedOrBornPawn(baby, mother)) { if (baby.playerSettings != null && mother.playerSettings != null) { baby.playerSettings.AreaRestriction = mother.playerSettings.AreaRestriction; } if (baby.RaceProps.IsFlesh) { baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, mother); if (father != null) { baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, father); } } // Good until otherwise proven bad bool successful_birth = true; var disabledBaby = BackstoryDatabase.allBackstories ["CustomBackstory_NA_Childhood_Disabled"]; if (disabledBaby != null) { baby.story.childhood = disabledBaby; } else { Log.Error("Couldn't find the required Backstory: CustomBackstory_NA_Childhood_Disabled!"); baby.story.childhood = null; } baby.story.adulthood = null; baby.workSettings.Disable(WorkTypeDefOf.Hunting); //hushes up the "has no ranged weapon" alert // remove all traits baby.story.traits.allTraits.Clear(); // Add some genetic traits if (traitpool.Count > 0) { for (int j = 0; j != 2; j++) { Trait gentrait = traitpool.RandomElement(); if (!baby.story.traits.HasTrait(gentrait.def)) { baby.story.traits.GainTrait(gentrait); } } } // Move the baby in front of the mother, rather than on top if (mother.CurrentBed() != null) { baby.Position = baby.Position + new IntVec3(0, 0, 1).RotatedBy(mother.CurrentBed().Rotation); } // else // baby.Position = baby.Position + new IntVec3 (0, 0, 1).RotatedBy (mother.Rotation); // The baby died from bad chance of success if (Rand.Value > chance_successful || chance_successful == 0) { successful_birth = false; } // Birth defects via drugs or alcohol if (mother.health.hediffSet.HasHediff(HediffDef.Named("BirthDefectTracker"))) { Hediff_BirthDefectTracker tracker = (Hediff_BirthDefectTracker)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("BirthDefectTracker")); // The baby died in utero from chemical affect if (tracker.stillbirth) { successful_birth = false; } // The baby lived! So far, anyways else { // Should the baby get fetal alcohol syndrome? if (tracker.fetal_alcohol) { baby.health.AddHediff(HediffDef.Named("FetalAlcoholSyndrome")); } // If the mother got high while pregnant, crongrats retard // now your baby is addicted to crack if (tracker.drug_addictions.Count > 0) { foreach (HediffDef addiction in tracker.drug_addictions) { baby.health.AddHediff(addiction, null, null); } } } } if (father != null) { // Inbred? if (mother.relations.FamilyByBlood.Contains <Pawn> (father)) { // 50% chance to get a birth defect from inbreeding if (Rand.Range(0, 1) == 1) { GiveRandomBirthDefect(baby); if (baby.health.hediffSet.HasHediff(HediffDef.Named("DefectStillborn"))) { successful_birth = false; } } } if (successful_birth == true) { // The father is happy the baby was born //father.needs.mood.thoughts.memories.TryGainMemoryThought (ThoughtDef.Named ("PartnerGaveBirth")); father.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("PartnerGaveBirth")); } } // The baby was born! Yay! if (successful_birth == true) { // Send a message that the baby was born if (mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("HumanPregnancy")).Visible&& PawnUtility.ShouldSendNotificationAbout(mother)) { //Messages.Message ("MessageGaveBirth".Translate (new object[] {mother.LabelIndefinite ()}).CapitalizeFirst (), mother, MessageSound.Benefit); Find.LetterStack.ReceiveLetter("LabelGaveBirth".Translate(new object[] { baby.LabelIndefinite() }), "MessageHumanBirth".Translate(new object[] { mother.LabelIndefinite(), baby.Name.ToStringShort }), LetterDefOf.Good, baby, null); } // Try to give PPD. If not, give "New baby" thought float chance = 0.2f; if (mother.story.traits.HasTrait(TraitDefOf.Psychopath)) { chance -= 1; } if (mother.story.traits.HasTrait(TraitDef.Named("Nerves"))) { chance -= 0.2f * mother.story.traits.GetTrait(TraitDef.Named("Nerves")).Degree; } else if (mother.story.traits.HasTrait(TraitDef.Named("NaturalMood"))) { if (mother.story.traits.GetTrait(TraitDef.Named("NaturalMood")).Degree == 2) { chance -= 1; } if (mother.story.traits.GetTrait(TraitDef.Named("NaturalMood")).Degree == -2) { chance += 0.6f; } // For some reason this is broken /*} else if (mother.story.traits.HasTrait (TraitDef.Named ("Neurotic"))) { * if (mother.story.traits.GetTrait (TraitDef.Named ("Neurotic")).Degree == 1) { * chance += 0.2f; * } else * chance += 0.4f;*/ } // Because for whatever dumb reason the Math class doesn't have a Clamp method if (chance < 0) { chance = 0; } if (chance > 1) { chance = 1; } Log.Message("Debugging: Chance of PPD is " + chance * 100 + "%"); // Try to give PPD if (Rand.Value < chance) { mother.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("PostPartumDepression"), null); bool verybad = false; if (mother.story.traits.HasTrait(TraitDef.Named("NaturalMood"))) { if (mother.story.traits.GetTrait(TraitDef.Named("NaturalMood")).Degree == -2) { verybad = true; } } else if (mother.story.traits.HasTrait(TraitDef.Named("Neurotic"))) { if (mother.story.traits.GetTrait(TraitDef.Named("Neurotic")).Degree == 2) { verybad = true; } } // This pawn gets an exceptionally bad case of PPD if (verybad) { foreach (Thought_Memory thought in mother.needs.mood.thoughts.memories.Memories) { if (thought.def.defName == "PostPartumDepression") { thought.SetForcedStage(thought.CurStageIndex + 1); } } } } else { // If we didn't get PPD, then the pawn gets a mood buff if (mother.health.hediffSet.HasHediff(HediffDef.Named("GaveBirthFlag")) == false) { mother.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("IGaveBirthFirstTime")); } else { mother.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("IGaveBirth")); } } } // The birth was not successful if (successful_birth == false) { bool aborted = false; if (chance_successful < 0f) { aborted = true; } if (baby != null) { Miscarry(baby, aborted); } } } else { Find.WorldPawns.PassToWorld(baby, PawnDiscardDecideMode.Discard); } } if (mother.Spawned) { // Spawn guck FilthMaker.MakeFilth(mother.Position, mother.Map, ThingDefOf.FilthAmnioticFluid, mother.LabelIndefinite(), 5); if (mother.caller != null) { mother.caller.DoCall(); } if (baby != null) { if (baby.caller != null) { baby.caller.DoCall(); } } Log.Message("Birth quality = " + birthing_quality); // Possible tearing from pregnancy if (birthing_quality < 0.75f) { if (birthing_quality < Rand.Value) { // Add a tear from giving birth if (birthing_quality < Rand.Value) { mother.health.AddHediff(HediffDef.Named("PregnancyTearMajor"), ChildrenUtility.GetPawnBodyPart(mother, "Torso"), null); } else { mother.health.AddHediff(HediffDef.Named("PregnancyTear"), ChildrenUtility.GetPawnBodyPart(mother, "Torso"), null); } } } } pawn.health.RemoveHediff(pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth"))); pawn.health.RemoveHediff(this); }
public static void GiveVitaeEffects(Pawn receiver, Pawn donor) { var pawn = receiver; //Give Vitae High Effect Hediff vitaeHighHediff = HediffMaker.MakeHediff(VampDefOf.ROMV_VitaeHigh, pawn, null); float numHigh = 0.75f; AddictionUtility.ModifyChemicalEffectForToleranceAndBodySize(pawn, VampDefOf.ROMV_VitaeChemical, ref numHigh); vitaeHighHediff.Severity = numHigh; pawn.health.AddHediff(vitaeHighHediff, null, null); //Give Vitae Tolerance Effect Hediff vitaeToleranceHediff = HediffMaker.MakeHediff(VampDefOf.ROMV_VitaeTolerance, pawn, null); float numTol = 0.035f; numTol /= receiver.BodySize; AddictionUtility.ModifyChemicalEffectForToleranceAndBodySize(pawn, VampDefOf.ROMV_VitaeChemical, ref numTol); vitaeToleranceHediff.Severity = numTol; pawn.health.AddHediff(vitaeToleranceHediff, null, null); const float addictiveness = 1.0f; const float minToleranceToAddict = 0.01f; const float existingAddictionSeverityOffset = 0.2f; var needLevelOffset = 1f; var overdoseSeverityOffset = new FloatRange(0.18f, 0.35f); var chemical = VampDefOf.ROMV_VitaeChemical; var addictionHediffDef = VampDefOf.ROMV_VitaeAddiction; var lookTarget = receiver; var hediff = AddictionUtility.FindToleranceHediff(lookTarget, VampDefOf.ROMV_VitaeChemical); var num = hediff?.Severity ?? 0f; var hediffAddiction = AddictionUtility.FindAddictionHediff(lookTarget, VampDefOf.ROMV_VitaeChemical); if (hediffAddiction != null) { hediffAddiction.Severity += existingAddictionSeverityOffset; } else if (Rand.Value < addictiveness && num >= minToleranceToAddict) { lookTarget.health.AddHediff(addictionHediffDef, null, null); if (PawnUtility.ShouldSendNotificationAbout(lookTarget)) { Find.LetterStack.ReceiveLetter("LetterLabelNewlyAddicted".Translate(new object[] { chemical.label }).CapitalizeFirst(), "LetterNewlyAddicted".Translate(new object[] { lookTarget.LabelShort, chemical.label }).AdjustedFor(lookTarget).CapitalizeFirst(), LetterDefOf.NegativeEvent, lookTarget, null); } AddictionUtility.CheckDrugAddictionTeachOpportunity(lookTarget); } if (addictionHediffDef.causesNeed != null) { var need = lookTarget.needs.AllNeeds.Find((Need x) => x.def == addictionHediffDef.causesNeed); if (need != null) { AddictionUtility.ModifyChemicalEffectForToleranceAndBodySize(lookTarget, chemical, ref needLevelOffset); need.CurLevel += needLevelOffset; } } // var firstHediffOfDef = lookTarget.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.DrugOverdose, false); // var num2 = firstHediffOfDef?.Severity ?? 0f; // if (num2 < 0.9f && Rand.Value < largeOverdoseChance) // { // var num3 = Rand.Range(0.85f, 0.99f); // HealthUtility.AdjustSeverity(lookTarget, HediffDefOf.DrugOverdose, num3 - num2); // if (lookTarget.Faction == Faction.OfPlayer) // { // Messages.Message("MessageAccidentalOverdose".Translate(new object[] // { // lookTarget.LabelIndefinite(), // chemical.LabelCap // }).CapitalizeFirst(), MessageTypeDefOf.NegativeHealthEvent); // } // } // else // { // var num4 = overdoseSeverityOffset.RandomInRange / lookTarget.BodySize; // if (num4 > 0f) // { // HealthUtility.AdjustSeverity(lookTarget, HediffDefOf.DrugOverdose, num4); // } // } }
public override void Tick() { // Something has gone horribly wrong if (pawn.health.hediffSet.HasHediff(HediffDef.Named("PostPregnancy"))) { Log.Error("HumanPregnancy Hediff was not properly removed when pawn " + pawn.NameStringShort + " gave birth."); // delet this if (pawn.health.hediffSet.HasHediff(HediffDef.Named("GivingBirth"))) { pawn.health.RemoveHediff(pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth"))); } pawn.health.RemoveHediff(this); } this.ageTicks++; if (this.pawn.IsHashIntervalTick(1000)) { if (this.pawn.needs.food != null && this.pawn.needs.food.CurCategory == HungerCategory.Starving && Rand.MTBEventOccurs(0.5f, 60000, 1000)) { if (this.Visible && PawnUtility.ShouldSendNotificationAbout(this.pawn)) { Messages.Message("MessageMiscarriedStarvation".Translate(new object[] { this.pawn.LabelIndefinite() }).CapitalizeFirst(), this.pawn, MessageSound.Negative); } Miscarry(false); return; } if (this.IsSeverelyWounded && Rand.MTBEventOccurs(0.5f, 60000, 1000)) { if (this.Visible && PawnUtility.ShouldSendNotificationAbout(this.pawn)) { Messages.Message("MessageMiscarriedPoorHealth".Translate(new object[] { this.pawn.LabelIndefinite() }).CapitalizeFirst(), this.pawn, MessageSound.Negative); } Miscarry(false); return; } } GestationProgress += 1 / (pawn.RaceProps.gestationPeriodDays * 60000); // Discover from if (!is_discovered) { if ((GestationProgress > 0.25f && pawn.story.bodyType != BodyType.Fat) || (GestationProgress > 0.1f && pawn.story.bodyType == BodyType.Thin)) { DiscoverPregnancy(); } } // Final stage of pregnancy if (CurStageIndex == 3) { if (!pawn.health.hediffSet.HasHediff(HediffDef.Named("GivingBirth"))) { // Notify the player birth is near if (Visible && PawnUtility.ShouldSendNotificationAbout(pawn)) { Messages.Message("MessageHavingContractions".Translate(new object[] { pawn.LabelIndefinite() }).CapitalizeFirst(), pawn, MessageSound.Standard); } // Give the mother the GivingBirth hediff pawn.health.AddHediff(HediffDef.Named("GivingBirth"), ChildrenUtility.GetPawnBodyPart(pawn, "Torso"), null); } // We're having contractions now else { // Has the pregnancy been tended to? if (pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth")).IsTended()) { // Then we get a safe pregnancy DoBirthSpawn(pawn, father, 1); } // natural birth (probably not a good idea!) else if (GestationProgress >= 1) { // Do risky pregnancy DoBirthSpawn(pawn, father, 0.9f); if (Rand.Value <= 0.1f) { pawn.health.AddHediff(HediffDef.Named("PlacentaBleed"), ChildrenUtility.GetPawnBodyPart(pawn, "Torso"), null); } } } } /*if (this.GestationProgress >= 1) { * if (this.Visible && PawnUtility.ShouldSendNotificationAbout (this.pawn)) { * Messages.Message ("MessageGaveBirth".Translate (new object[] { * this.pawn.LabelIndefinite () * }).CapitalizeFirst (), this.pawn, MessageSound.Benefit); * } * Hediff_Pregnant.DoBirthSpawn (this.pawn, this.father); * }*/ }
public override void Tick() { ageTicks++; if (pawn.IsHashIntervalTick(PawnStateCheckInterval)) { //Log.Message("Father = " + father); if (pawn.needs.food != null && pawn.needs.food.CurCategory == HungerCategory.Starving && Rand.MTBEventOccurs(0.5f, 60000f, 1000f)) { if (Visible && PawnUtility.ShouldSendNotificationAbout(pawn)) { //Messages.Message("MessageMiscarriedStarvation".Translate(pawn.LabelIndefinite()).CapitalizeFirst(), pawn, MessageTypeDefOf.NegativeHealthEvent); Messages.Message("MessageMiscarriedStarvation".Translate(new object[] { pawn.LabelIndefinite() }).CapitalizeFirst(), pawn, MessageTypeDefOf.NegativeHealthEvent); } Miscarry(); return; } if (IsSeverelyWounded && Rand.MTBEventOccurs(0.5f, 60000f, 1000f)) { if (Visible && PawnUtility.ShouldSendNotificationAbout(pawn)) { //Messages.Message("MessageMiscarriedPoorHealth".Translate(pawn.LabelIndefinite()).CapitalizeFirst(), pawn, MessageTypeDefOf.NegativeHealthEvent); Messages.Message("MessageMiscarriedPoorHealth".Translate(new object[] { pawn.LabelIndefinite() }).CapitalizeFirst(), pawn, MessageTypeDefOf.NegativeHealthEvent); } Miscarry(); return; } if (GestationProgress >= 1f) { /* * if (Visible && PawnUtility.ShouldSendNotificationAbout(pawn)) * { * Messages.Message("MessageAvaliLayedAnEgg".Translate(new object[] * { * pawn.LabelIndefinite() * }).CapitalizeFirst(), pawn, MessageTypeDefOf.PositiveEvent); * } */ /* * if (Visible && PawnUtility.ShouldSendNotificationAbout(pawn)) * { * * Messages.Message("MessageLayedEgg".Translate(new object[] * { * this.pawn.LabelIndefinite() * }).CapitalizeFirst(), this.pawn, MessageTypeDefOf.PositiveEvent); * } */ //Log.Message(pawn + " try to start job GotoLayAvaliEgg"); //Log.Message(pawn + " egg.father = " + father); //Log.Message(pawn + " bed = " + RestUtility.FindBedFor(pawn)); Job newJob = null; Building_Bed bed = RestUtility.FindBedFor(pawn); if (bed != null) { newJob = new Job(JobDefOf.GotoLayAvaliEgg, father, bed); } else { IntVec3 cell = RCellFinder.RandomWanderDestFor(pawn, pawn.Position, 5f, null, Danger.Some); newJob = new Job(JobDefOf.GotoLayAvaliEgg, father, cell); } pawn.jobs.StartJob(newJob, JobCondition.InterruptForced, null, false, true, null, null, false); //Hediff_AvaliHasEgg.LayEgg(this.pawn, this.father); //this.pawn.health.RemoveHediff(this); } } if (GestationProgress < 1f) { GestationProgress += 1f / (pawn.RaceProps.gestationPeriodDays * 60000f); } }
protected override IEnumerable <Toil> MakeNewToils() { /* * * Toil Configurations * */ Toil prepareToSpin = new Toil(); prepareToSpin.initAction = delegate { if (Prey == null && Corpse == null) { this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } if (Prey.Dead) { this.pawn.CurJob.SetTarget(TargetIndex.A, Prey.Corpse); } }; Toil gotoBody = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); gotoBody.AddPreInitAction(new Action(delegate { this.pawn.ClearAllReservations(); this.pawn.Reserve(TargetA, this.job); //this.Map.physicalInteractionReservationManager.ReleaseAllForTarget(TargetA); //this.Map.physicalInteractionReservationManager.Reserve(this.GetActor(), TargetA); currentActivity = "Spinning Cocoon"; })); Toil spinDelay = new Toil { defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = 500, initAction = delegate { currentActivity = "Spinning Cocoon"; } }; spinDelay.WithProgressBarToilDelay(TargetIndex.B); Toil spinBody = new Toil { initAction = delegate { //Log.Message("5"); var spinner = this.GetActor() as Spider; if (spinner != null) { Building_Cocoon newCocoon; Thing toLoad; IntVec3 newPosition; if (Prey.Dead) { toLoad = Prey.Corpse; newPosition = Prey.Corpse.Position; } else { toLoad = Prey; newPosition = Prey.Position; } if (!toLoad.Spawned) { this.EndJobWith(JobCondition.Incompletable); return; } toLoad.DeSpawn(); toLoad.holdingOwner = null; if (!GenConstruct.CanPlaceBlueprintAt(CocoonDef, newPosition, Rot4.North, this.pawn.Map).Accepted) { var cells = GenAdj.CellsAdjacent8Way(new TargetInfo(newPosition, this.pawn.Map)); foreach (IntVec3 cell in cells) { if (GenConstruct.CanPlaceBlueprintAt(CocoonDef, cell, Rot4.North, this.Map).Accepted) { newPosition = cell; break; } } } newCocoon = (Building_Cocoon)GenSpawn.Spawn(CocoonDef, newPosition, spinner.Map); //Log.Message("New Spinner: " + newCocoon.Spinner.Label); newCocoon.TryGetInnerInteractableThingOwner().TryAdd(toLoad); this.pawn?.CurJob?.SetTarget(TargetIndex.B, newCocoon); } }, defaultCompleteMode = ToilCompleteMode.Instant }; Toil pickupCocoon = Toils_Haul.StartCarryThing(TargetIndex.B); pickupCocoon.AddPreInitAction(new Action(delegate { //this.TargetB.Thing.DeSpawn(); this.pawn.CurJob.SetTarget(TargetIndex.C, TargetB.Thing); this.pawn.Reserve(TargetC, this.job); //this.pawn.Map.physicalInteractionReservationManager.Reserve(this.pawn, TargetC); })); Toil relocateCocoon = Toils_Haul.CarryHauledThingToCell(TargetIndex.C); Toil dropCocoon = Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, relocateCocoon, false).FailOn(() => !GenConstruct.CanPlaceBlueprintAt(CocoonDef, TargetC.Cell, Rot4.North, this.Map).Accepted); this.AddFinishAction(new Action(delegate { this.pawn.Map.physicalInteractionReservationManager.ReleaseAllClaimedBy(this.pawn); })); /* * * Toil Execution * */ yield return(new Toil { initAction = delegate { this.Map.attackTargetsCache.UpdateTarget(this.pawn); }, atomicWithPrevious = true, defaultCompleteMode = ToilCompleteMode.Instant }); Action onHitAction = delegate { Pawn prey = this.Prey; bool surpriseAttack = this.firstHit && !prey.IsColonist; if (this.pawn.meleeVerbs.TryMeleeAttack(prey, this.job.verbToUse, surpriseAttack)) { if (!this.notifiedPlayer && PawnUtility.ShouldSendNotificationAbout(prey)) { this.notifiedPlayer = true; Messages.Message("MessageAttackedByPredator".Translate(new object[] { prey.LabelShort, this.pawn.LabelIndefinite() }).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatBig);// MessageSound.SeriousAlert); } this.Map.attackTargetsCache.UpdateTarget(this.pawn); } this.firstHit = false; }; //yield return Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, onHitAction).JumpIf(() => Prey.Downed || Prey.Dead, prepareToSpin).FailOn(() => Find.TickManager.TicksGame > this.startTick + 5000 && (float)(this.job.GetTarget(TargetIndex.A).Cell - this.pawn.Position).LengthHorizontalSquared > 4f); yield return(prepareToSpin.FailOn(() => Prey == null)); yield return(gotoBody.FailOn(() => Prey == null)); yield return(spinDelay.FailOn(() => Prey == null)); yield return(spinBody.FailOn(() => Prey == null)); //yield return pickupCocoon; //yield return relocateCocoon; //yield return dropCocoon; //float durationMultiplier = 1f / this.pawn.GetStatValue(StatDefOf.EatingSpeed, true); //yield return Toils_Ingest.ChewIngestible(this.pawn, durationMultiplier, TargetIndex.A, TargetIndex.None).FailOnDespawnedOrNull(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch); //yield return Toils_Ingest.FinalizeIngest(this.pawn, TargetIndex.A); //yield return Toils_Jump.JumpIf(gotoCorpse, () => this.pawn.needs.food.CurLevelPercentage < 0.9f); }
public bool TryStartMentalState(MentalStateDef stateDef, string reason = null, bool forceWake = false, bool causedByMood = false, Pawn otherPawn = null, bool transitionSilently = false) { if ((!pawn.Spawned && !pawn.IsCaravanMember()) || CurStateDef == stateDef || pawn.Downed || (!forceWake && !pawn.Awake())) { return(false); } if (TutorSystem.TutorialMode && pawn.Faction == Faction.OfPlayer) { return(false); } if (!stateDef.Worker.StateCanOccur(pawn)) { return(false); } MentalState mentalState = (MentalState)Activator.CreateInstance(stateDef.stateClass); mentalState.pawn = pawn; mentalState.def = stateDef; mentalState.causedByMood = causedByMood; if (otherPawn != null) { ((MentalState_SocialFighting)mentalState).otherPawn = otherPawn; } mentalState.PreStart(); if (!transitionSilently) { if ((pawn.IsColonist || pawn.HostFaction == Faction.OfPlayer) && stateDef.tale != null) { TaleRecorder.RecordTale(stateDef.tale, pawn); } if (stateDef.IsExtreme && pawn.IsPlayerControlledCaravanMember()) { Messages.Message("MessageCaravanMemberHasExtremeMentalBreak".Translate(), pawn.GetCaravan(), MessageTypeDefOf.ThreatSmall); } pawn.records.Increment(RecordDefOf.TimesInMentalState); } if (pawn.Drafted) { pawn.drafter.Drafted = false; } curStateInt = mentalState; if (pawn.needs.mood != null) { pawn.needs.mood.thoughts.situational.Notify_SituationalThoughtsDirty(); } if (stateDef != null && stateDef.IsAggro && pawn.caller != null) { pawn.caller.Notify_InAggroMentalState(); } if (curStateInt != null) { curStateInt.PostStart(reason); } if (pawn.CurJob != null) { pawn.jobs.StopAll(); } if (pawn.Spawned) { pawn.Map.attackTargetsCache.UpdateTarget(pawn); } if (pawn.Spawned && forceWake && !pawn.Awake()) { pawn.jobs.EndCurrentJob(JobCondition.InterruptForced); } if (!transitionSilently && PawnUtility.ShouldSendNotificationAbout(pawn)) { string text = mentalState.GetBeginLetterText(); if (!text.NullOrEmpty()) { string label = (stateDef.beginLetterLabel ?? stateDef.LabelCap).CapitalizeFirst() + ": " + pawn.LabelShortCap; if (!reason.NullOrEmpty()) { text = text + "\n\n" + reason; } Find.LetterStack.ReceiveLetter(label, text, stateDef.beginLetterDef, pawn); } } return(true); }
public virtual void Tick() { this.ageTicks++; if (this.def.hediffGivers != null && this.pawn.IsHashIntervalTick(60)) { for (int i = 0; i < this.def.hediffGivers.Count; i++) { this.def.hediffGivers[i].OnIntervalPassed(this.pawn, this); } } if (this.Visible && !this.visible) { this.visible = true; if (this.def.taleOnVisible != null) { TaleRecorder.RecordTale(this.def.taleOnVisible, new object[] { this.pawn, this.def }); } } HediffStage curStage = this.CurStage; if (curStage != null) { if (curStage.hediffGivers != null && this.pawn.IsHashIntervalTick(60)) { for (int j = 0; j < curStage.hediffGivers.Count; j++) { curStage.hediffGivers[j].OnIntervalPassed(this.pawn, this); } } if (curStage.mentalStateGivers != null && this.pawn.IsHashIntervalTick(60) && !this.pawn.InMentalState) { for (int k = 0; k < curStage.mentalStateGivers.Count; k++) { MentalStateGiver mentalStateGiver = curStage.mentalStateGivers[k]; if (Rand.MTBEventOccurs(mentalStateGiver.mtbDays, 60000f, 60f)) { this.pawn.mindState.mentalStateHandler.TryStartMentalState(mentalStateGiver.mentalState, null, false, false, null, false); } } } MentalBreakDef mentalBreakDef; if (curStage.mentalBreakMtbDays > 0f && this.pawn.IsHashIntervalTick(60) && !this.pawn.InMentalState && Rand.MTBEventOccurs(curStage.mentalBreakMtbDays, 60000f, 60f) && (from x in DefDatabase <MentalBreakDef> .AllDefsListForReading where x.Worker.BreakCanOccur(this.pawn) select x).TryRandomElementByWeight((MentalBreakDef x) => x.Worker.CommonalityFor(this.pawn), out mentalBreakDef)) { mentalBreakDef.Worker.TryStart(this.pawn, null, false); } if (curStage.vomitMtbDays > 0f && this.pawn.IsHashIntervalTick(600) && Rand.MTBEventOccurs(curStage.vomitMtbDays, 60000f, 600f) && this.pawn.Spawned && this.pawn.Awake()) { this.pawn.jobs.StartJob(new Job(JobDefOf.Vomit), JobCondition.InterruptForced, null, true, true, null, null, false); } Thought_Memory th; if (curStage.forgetMemoryThoughtMtbDays > 0f && this.pawn.needs.mood != null && this.pawn.IsHashIntervalTick(400) && Rand.MTBEventOccurs(curStage.forgetMemoryThoughtMtbDays, 60000f, 400f) && this.pawn.needs.mood.thoughts.memories.Memories.TryRandomElement(out th)) { this.pawn.needs.mood.thoughts.memories.RemoveMemory(th); } if (!this.recordedTale && curStage.tale != null) { TaleRecorder.RecordTale(curStage.tale, new object[] { this.pawn }); this.recordedTale = true; } if (curStage.destroyPart && this.Part != null && this.Part != this.pawn.RaceProps.body.corePart) { this.pawn.health.AddHediff(HediffDefOf.MissingBodyPart, this.Part, null, null); } if (curStage.deathMtbDays > 0f && this.pawn.IsHashIntervalTick(200) && Rand.MTBEventOccurs(curStage.deathMtbDays, 60000f, 200f)) { bool flag = PawnUtility.ShouldSendNotificationAbout(this.pawn); Caravan caravan = this.pawn.GetCaravan(); this.pawn.Kill(null, null); if (flag) { this.pawn.health.NotifyPlayerOfKilled(null, this, caravan); } return; } } }
public override IEnumerable <Toil> MakeNewToils() { base.AddFinishAction(delegate { this.Map.attackTargetsCache.UpdateTarget(this.pawn); }); Toil prepareToEatCorpse = new Toil(); prepareToEatCorpse.initAction = delegate() { Pawn actor = prepareToEatCorpse.actor; Corpse corpse = this.Corpse; if (corpse == null) { Pawn prey = this.Prey; if (prey == null) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true, true); return; } corpse = prey.Corpse; if (corpse == null || !corpse.Spawned) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true, true); return; } } if (actor.Faction == Faction.OfPlayer) { corpse.SetForbidden(false, false); } else { corpse.SetForbidden(true, false); } actor.CurJob.SetTarget(TargetIndex.A, corpse); }; yield return(Toils_General.DoAtomic(delegate { this.Map.attackTargetsCache.UpdateTarget(this.pawn); })); Action hitAction = delegate() { Pawn prey = this.Prey; bool surpriseAttack = this.firstHit && !prey.IsColonist; if (this.pawn.meleeVerbs.TryMeleeAttack(prey, this.job.verbToUse, surpriseAttack)) { if (!this.notifiedPlayerAttacked && PawnUtility.ShouldSendNotificationAbout(prey)) { this.notifiedPlayerAttacked = true; Messages.Message("MessageAttackedByPredator".Translate(prey.LabelShort, this.pawn.LabelIndefinite(), prey.Named("PREY"), this.pawn.Named("PREDATOR")).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatSmall, true); } this.Map.attackTargetsCache.UpdateTarget(this.pawn); this.firstHit = false; } }; Toil toil = Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, hitAction).JumpIfDespawnedOrNull(TargetIndex.A, prepareToEatCorpse).JumpIf(() => this.Corpse != null, prepareToEatCorpse).FailOn(() => Find.TickManager.TicksGame > this.startTick + 5000 && (float)(this.job.GetTarget(TargetIndex.A).Cell - this.pawn.Position).LengthHorizontalSquared > 4f); toil.AddPreTickAction(new Action(this.CheckWarnPlayer)); yield return(toil); yield return(prepareToEatCorpse); Toil gotoCorpse = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); yield return(gotoCorpse); float durationMultiplier = 1f / this.pawn.GetStatValue(StatDefOf.EatingSpeed, true); yield return(Toils_Ingest.ChewIngestible(this.pawn, durationMultiplier, TargetIndex.A, TargetIndex.None).FailOnDespawnedOrNull(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch)); yield return(Toils_Ingest.FinalizeIngest(this.pawn, TargetIndex.A)); yield return(Toils_Jump.JumpIf(gotoCorpse, () => this.pawn.needs.food.CurLevelPercentage < 0.9f)); yield break; }
public override void ApplyOnPawn(Pawn pawn, BodyPartRecord part, Pawn billDoer, List <Thing> ingredients, Bill bill) { if (billDoer != null) { if (base.CheckSurgeryFail(billDoer, pawn, ingredients, part, bill)) { return; } TaleRecorder.RecordTale(TaleDefOf.DidSurgery, new object[] { billDoer, pawn }); if (PawnUtility.ShouldSendNotificationAbout(pawn) || PawnUtility.ShouldSendNotificationAbout(billDoer)) { string text; if (!this.recipe.successfullyRemovedHediffMessage.NullOrEmpty()) { text = string.Format(this.recipe.successfullyRemovedHediffMessage, billDoer.LabelShort, pawn.LabelShort); } else { text = "MessageSuccessfullyRemovedHediff".Translate(billDoer.LabelShort, pawn.LabelShort, this.recipe.removesHediff.label.Named("HEDIFF"), billDoer.Named("SURGEON"), pawn.Named("PATIENT")); } Messages.Message(text, pawn, MessageTypeDefOf.PositiveEvent, true); } } Hediff hediff = pawn.health.hediffSet.hediffs.Find((Hediff x) => x.def == this.recipe.removesHediff && x.Part == null /* part */ && x.Visible); if (hediff != null) { pawn.health.RemoveHediff(hediff); } if (bill.recipe.HasModExtension <HediffExtension>()) { foreach (HediffDef extraHediffDef in bill.recipe.GetModExtension <HediffExtension>().extraHediffs) { hediff = pawn.health.hediffSet.hediffs.Find((Hediff x) => x.def == extraHediffDef && x.Part == null /* part */ && x.Visible); if (hediff != null) { pawn.health.RemoveHediff(hediff); } } } BodyPartRecord bodyPartRecord; DamageDef damageType = DamageDefOf.Bomb; Random random = new Random(); int damageDealt = 99999; int injuries = random.Next(1, 6); for (int i = 0; i < injuries; i++) { if (!pawn.health.Dead) { bodyPartRecord = GetPart(pawn); //Log.Message(bodyPartRecord.Label); pawn.TakeDamage(new DamageInfo(damageType, damageDealt, -1f, -1f, billDoer, bodyPartRecord, null, DamageInfo.SourceCategory.ThingOrUnknown)); if (pawn.health.hediffSet.GetBrain() == null || bodyPartRecord.Label.Equals("brain")) { i = 10000000; break; } } else { //Log.Message("In the else"); break; } } }