Ejemplo n.º 1
0
 private static void Postfix(ref bool __result, ref WorkGiver_Tend __instance, Pawn pawn, Thing t, bool forced)
 {
     if (__result || t == pawn && !(__instance is WorkGiver_TendSelf))
     {
         return;
     }
     if (t is Pawn target && target.IsCaptiveOf(pawn.Faction) &&
         !pawn.WorkTypeIsDisabled(WorkTypeDefOf.Doctor) &&
         (!__instance.def.tendToHumanlikesOnly || target.RaceProps.Humanlike && !target.IsWildMan()) &&
         (!__instance.def.tendToAnimalsOnly || target.AnimalOrWildMan()) &&
         target.GetPosture() != PawnPosture.Standing && HealthAIUtility.ShouldBeTendedNowByPlayer(target) &&
         pawn.CanReserve(target, 1, -1, null, forced))
     {
         __result = true;
     }
 }
        public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            bool result = false;
            Pawn pawn2  = t as Pawn;

            if (pawn.story.traits.HasTrait(WizardryDefOf.LotRW_Istari))
            {
                CompWizardry comp        = pawn.GetComp <CompWizardry>();
                PawnAbility  pawnAbility = comp.AbilityData.Powers.FirstOrDefault((PawnAbility x) => x.Def == WizardryDefOf.LotRW_Nienna_HealingTouch);
                if (pawn2 != null && (!this.def.tendToHumanlikesOnly || pawn2.RaceProps.Humanlike) && (!this.def.tendToAnimalsOnly || pawn2.RaceProps.Animal) && WorkGiver_Tend.GoodLayingStatusForTend(pawn2, pawn) && HasHediffInjuries(pawn2) && pawn != pawn2 && pawnAbility.CooldownTicksLeft <= 0)
                {
                    LocalTargetInfo target = pawn2;
                    if (pawn.CanReserve(target, 1, -1, null, forced))
                    {
                        return(true);
                    }
                }
            }
            return(result);
        }
Ejemplo n.º 3
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            // 患者の状態による失敗条件

            // 死んだりいなくなったりしたら失敗
            this.FailOnDespawnedNullOrForbidden(PatientInd);
            this.FailOn(
                () =>
            {
                // 寝ていない状態になったら失敗
                if (!WorkGiver_Tend.GoodLayingStatusForTend(Patient, pawn))
                {
                    return(true);
                }

                // 看護師と患者が同一人物だったら失敗
                return(pawn == Patient);
            });

            // 精神崩壊状態次第で失敗とする
            this.FailOnAggroMentalState(PatientInd);
            AddEndCondition(
                delegate
            {
                // 看病が必要な状況なら続ける
                // 免疫を得る系の病気を持っている&看病Hediffが無い
                if (Patient.health.hediffSet.GetFirstHediffOfDef(MizuDef.Hediff_Nursed) == null)
                {
                    return(JobCondition.Ongoing);
                }

                // 既に看病されていたら終了
                return(JobCondition.Succeeded);
            });

            // ツールまで移動
            yield return(Toils_Goto.GotoThing(ToolInd, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(ToolInd));

            // ツールを手に取る
            yield return(Toils_Haul.StartCarryThing(ToolInd));

            // 患者の元へ移動
            yield return(Toils_Goto.GotoThing(PatientInd, PathEndMode.Touch));

            // 看病
            var workToil = new Toil
            {
                initAction = () =>

                             // 必要工数の計算
                             ticksLeftThisToil = WorkTicks,

                // 細々とした設定
                defaultCompleteMode = ToilCompleteMode.Delay
            };

            workToil.WithProgressBar(PatientInd, () => 1f - ((float)ticksLeftThisToil / WorkTicks), true);
            workToil.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
            yield return(workToil);

            // 看病完了時の処理
            var finishToil = new Toil
            {
                initAction = () =>
                {
                    // 看病状態追加
                    if (Patient.health.hediffSet.GetFirstHediffOfDef(MizuDef.Hediff_Nursed)
                        == null)
                    {
                        Patient.health.AddHediff(
                            HediffMaker.MakeHediff(MizuDef.Hediff_Nursed, Patient));
                    }

                    // 水減少
                    var comp = Tool.GetComp <CompWaterTool>();
                    comp.StoredWaterVolume -= ConsumeWaterVolume;
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            yield return(finishToil);

            // ツールを片付ける場所を決める
            yield return(Toils_Mizu.TryFindStoreCell(ToolInd, ToolPlaceInd));

            // 倉庫まで移動
            yield return(Toils_Goto.GotoCell(ToolPlaceInd, PathEndMode.Touch));

            // 倉庫に置く
            yield return(Toils_Haul.PlaceHauledThingInCell(ToolPlaceInd, null, true));
        }
Ejemplo n.º 4
0
 public static void PawnInCocoon(WorkGiver_Tend __instance, Pawn patient, Pawn doctor, ref bool __result)
 {
     __result = __result && (!patient.health.hediffSet.HasHediff(XenomorphDefOf.RRY_Hediff_Cocooned) && !(patient.CurrentBed() is Building_XenomorphCocoon));
     //    Log.Message(string.Format("WorkGiver_Tend_GoodLayingStatusForTend_Patch patient: {0}, doctor: {1}, __Result: {2}", patient, doctor, __result));
 }
Ejemplo n.º 5
0
        public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            var giver = t as Pawn;

            // 対象がポーンではない
            if (giver == null)
            {
                return(false);
            }

            // 自分自身の看病は出来ない
            if (pawn == t)
            {
                return(false);
            }

            // 対象を予約できない
            if (!pawn.CanReserve(giver, 1, -1, null, forced))
            {
                return(false);
            }

            // 人間用WorkGiverで相手が人間、または動物用WorkGiverで相手が動物、の組み合わせでない
            if (!((this.def.tendToHumanlikesOnly && giver.RaceProps.Humanlike) || (this.def.tendToAnimalsOnly && giver.RaceProps.Animal)))
            {
                return(false);
            }

            // 治療可能な体勢になっていない
            if (!WorkGiver_Tend.GoodLayingStatusForTend(giver, pawn))
            {
                return(false);
            }

            // 免疫を得て直すタイプの健康状態を持っていない
            // (治療状態は問わない)
            if (!giver.health.hediffSet.hediffs.Any((hediff) => hediff.def.PossibleToDevelopImmunityNaturally()))
            {
                return(false);
            }

            // 看病された効果が残っている
            if (giver.health.hediffSet.GetFirstHediffOfDef(MizuDef.Hediff_Nursed) != null)
            {
                return(false);
            }

            // 看病アイテムのチェック
            var mopList = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.HaulableAlways).Where((thing) =>
            {
                // 使用禁止チェック
                if (thing.IsForbidden(pawn))
                {
                    return(false);
                }

                var comp = thing.TryGetComp <CompWaterTool>();
                if (comp == null)
                {
                    return(false);
                }
                if (!comp.UseWorkType.Contains(CompProperties_WaterTool.UseWorkType.Nurse))
                {
                    return(false);
                }

                // 1回も使えないレベルの保有水量だったらダメ
                if (Mathf.Floor(comp.StoredWaterVolume / JobDriver_Nurse.ConsumeWaterVolume / 0.79f) <= 0)
                {
                    return(false);
                }

                return(true);
            });

            if (mopList.Count() == 0)
            {
                return(false);
            }
            if (mopList.Where((thing) => pawn.CanReserve(thing)).Count() == 0)
            {
                return(false);
            }

            return(true);
        }