예제 #1
0
        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);
            }
        }
예제 #2
0
        // 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;
        }
예제 #3
0
        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;
                }
            }
        }
예제 #4
0
        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;
                        }
                    }
                }
            }
        }
예제 #5
0
        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);
                //}
            });
        }
예제 #6
0
 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);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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);
             * }*/
        }
예제 #9
0
        /*
         * 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"));
                     *      }
                     *  }*/
                }
            }
        }
예제 #10
0
        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();
            }
        }
예제 #12
0
        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);
        }
예제 #13
0
        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;
                     }
                 }
             }
         }
     }
 }
예제 #15
0
        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);
        }
예제 #17
0
        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);
                    }
                }
            }
        }
예제 #18
0
        // 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);
                 }
             }
         }
     }
 }
예제 #20
0
        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);
        }
예제 #21
0
        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);
        }
예제 #23
0
        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);
             * }*/
        }
예제 #25
0
        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);
        }
예제 #27
0
        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);
        }
예제 #28
0
        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;
                }
            }
        }
예제 #29
0
        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;
        }
예제 #30
0
        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;
                }
            }
        }