예제 #1
0
        public static Job FeedJob(Pawn pawn)
        {
            Need_Blood blood = pawn.needs.TryGetNeed <Need_Blood>();

            if (blood == null)
            {
                return(null);
            }
            bool     desperate    = blood.CurCategory == HungerCategory.Starving;
            bool     isHuntHuman  = blood.preferredFeedMode == PreferredFeedMode.HumanoidLethal || blood.preferredFeedMode == PreferredFeedMode.HumanoidNonLethal;
            bool     isHuntLethal = blood.preferredFeedMode == PreferredFeedMode.HumanoidLethal || blood.preferredFeedMode == PreferredFeedMode.AnimalLethal;
            Thing    thing;
            ThingDef def;

            if (!BloodUtility.TryFindBestBloodSourceFor(pawn, pawn, desperate, out thing, out def))
            {
                return(null);
            }
            if (thing != null && thing != pawn && thing.Spawned)
            {
                Pawn pawn2 = thing as Pawn;
                if (pawn2 != null)
                {
                    return(new Job(VampDefOf.ROMV_Feed, pawn2)
                    {
                        killIncappedTarget = isHuntLethal
                    });
                }
                return(new Job(VampDefOf.ROMV_ConsumeBlood, thing)
                {
                    count = BloodUtility.WillConsumeStackCountOf(pawn, def)
                });
            }
            return(null);
        }
예제 #2
0
        // RimWorld.FoodUtility
        public static int WillConsumeStackCountOf(Pawn ingester, ThingDef def)
        {
            int num = Mathf.Min(10, BloodUtility.StackCountForBlood(def, ingester.VampComp().BloodPool.BloodWanted));

            if (num < 1)
            {
                num = 1;
            }
            return(num);
        }
예제 #3
0
        // RimWorld.FoodUtility
        public static Thing BestBloodSourceOnMap(Pawn getter, Pawn eater, bool desperate, BloodPreferabilty maxPref = BloodPreferabilty.Highblood, bool allowForbidden = false)
        {
            bool getterCanManipulate = getter.RaceProps.ToolUser && getter.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation);

            if (!getterCanManipulate && getter != eater)
            {
                Log.Error(string.Concat(new object[]
                {
                    getter,
                    " tried to find blood to bring to ",
                    eater,
                    " but ",
                    getter,
                    " is incapable of Manipulation."
                }));
                return(null);
            }

            BloodPreferabilty minPref = eater?.VampComp()?.Bloodline?.minBloodPref ?? BloodPreferabilty.Any;

            if (desperate)
            {
                minPref = eater?.VampComp()?.Bloodline?.desperateBloodPref ?? BloodPreferabilty.Any;
            }
            Predicate <Thing> foodValidator = delegate(Thing t)
            {
                if (t.TryGetComp <CompBloodItem>() is CompBloodItem bl)
                {
                    if (!allowForbidden && t.IsForbidden(getter))
                    {
                        return(false);
                    }
                    if ((int)bl.Props.bloodType < (int)minPref)
                    {
                        return(false);
                    }
                    if ((int)bl.Props.bloodType > (int)maxPref)
                    {
                        return(false);
                    }
                    if (t.IsBurning() || (!desperate && t.IsNotFresh()) || !getter.CanReserve(t, 1, -1, null, false))
                    {
                        return(false);
                    }
                    return(true);
                }
                return(false);
            };
            Thing             thing;
            Predicate <Thing> validator = foodValidator;

            thing = BloodUtility.SpawnedBloodItemScan(eater, getter.Position, getter.Map.listerThings.ThingsInGroup(ThingRequestGroup.FoodSourceNotPlantOrTree), PathEndMode.ClosestTouch, TraverseParms.For(getter, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator);
            return(thing);
        }
예제 #4
0
        // RimWorld.FoodUtility
        private static Pawn BestPawnToHuntForVampire(Pawn predator, bool desperate = false)
        {
            //if (predator.meleeVerbs.TryGetMeleeVerb() == null)
            //{
            //    return null;
            //}
            //bool flag = false;
            //float summaryHealthPercent = predator.health.summaryHealth.SummaryHealthPercent;
            //if (summaryHealthPercent < 0.25f)
            //{
            //    flag = true;
            //}
            List <Pawn> allPawnsSpawned = predator.Map.mapPawns.AllPawnsSpawned;
            Pawn        pawn            = null;
            float       num             = 0f;
            bool        tutorialMode    = TutorSystem.TutorialMode;

            for (int i = 0; i < allPawnsSpawned.Count; i++)
            {
                Pawn pawn2 = allPawnsSpawned[i];
                if (predator.GetRoom(RegionType.Set_Passable) == pawn2.GetRoom(RegionType.Set_Passable))
                {
                    if (predator != pawn2)
                    {
                        if (BloodUtility.IsAcceptableVictimFor(predator, pawn2, desperate))
                        {
                            if (predator.CanReach(pawn2, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                            {
                                if (!pawn2.IsForbidden(predator))
                                {
                                    if (!tutorialMode || pawn2.Faction != Faction.OfPlayer)
                                    {
                                        float preyScoreFor = FoodUtility.GetPreyScoreFor(predator, pawn2);
                                        if (preyScoreFor > num || pawn == null)
                                        {
                                            num  = preyScoreFor;
                                            pawn = pawn2;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(pawn);
        }
예제 #5
0
        // RimWorld.FoodUtility
        public static bool TryFindBestBloodSourceFor(Pawn getter, Pawn eater, bool desperate, out Thing bloodSource, out ThingDef bloodDef, bool canUseInventory = true, bool allowForbidden = false)
        {
            bool  flag  = getter.RaceProps.ToolUser && getter.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation);
            Thing thing = null;

            if (canUseInventory)
            {
                if (flag)
                {
                    thing = BloodUtility.BestBloodInInventory(getter, null, 0);
                }
                if (thing != null)
                {
                    if (getter.Faction != Faction.OfPlayer)
                    {
                        bloodSource = thing;
                        bloodDef    = thing.def;
                        return(true);
                    }
                    CompRottable compRottable = thing.TryGetComp <CompRottable>();
                    if (compRottable != null && compRottable.Stage == RotStage.Fresh && compRottable.TicksUntilRotAtCurrentTemp < 30000)
                    {
                        bloodSource = thing;
                        bloodDef    = thing.def;
                        return(true);
                    }
                }
            }
            Thing thing2 = BloodUtility.BestBloodSourceOnMap(getter, eater, desperate, BloodPreferabilty.Highblood, allowForbidden);

            if (thing == null && thing2 == null)
            {
                if (canUseInventory && flag)
                {
                    thing = BloodUtility.BestBloodInInventory(getter, null, 0);
                    if (thing != null)
                    {
                        bloodSource = thing;
                        bloodDef    = thing.def;
                        return(true);
                    }
                }
                if (thing2 == null && getter == eater)
                {
                    Pawn pawn = BloodUtility.BestPawnToHuntForVampire(getter);
                    if (pawn != null)
                    {
                        bloodSource = pawn;
                        bloodDef    = pawn.def;
                        return(true);
                    }
                }
                bloodSource = null;
                bloodDef    = null;
                return(false);
            }
            if (thing == null && thing2 != null)
            {
                bloodSource = thing2;
                bloodDef    = thing2.def;
                return(true);
            }
            if (thing2 == null && thing != null)
            {
                bloodSource = thing;
                bloodDef    = thing.def;
                return(true);
            }
            bloodSource = thing;
            bloodDef    = thing.def;
            return(false);
        }
예제 #6
0
        // RimWorld.FloatMenuMakerMap
        private static void Vamp_FloatMenus_Consume(Vector3 clickPos, Pawn pawn, ref List <FloatMenuOption> opts)
        {
            IntVec3     c             = IntVec3.FromVector3(clickPos);
            CompVampire selVampComp   = pawn.VampComp();
            bool        pawnIsVampire = pawn.IsVampire();

            if (selVampComp != null && pawnIsVampire)
            {
                //Hide food consumption from menus.
                Thing food = c.GetThingList(pawn.Map)
                             .FirstOrDefault(t => t.GetType() != typeof(Pawn) && t?.def?.ingestible != null);
                if (food != null)
                {
                    //string text = (!food.def.ingestible.ingestCommandString.NullOrEmpty()) ? string.Format(food.def.ingestible.ingestCommandString, food.LabelShort) : ((string)"ConsumeThing".Translate(food.LabelShort, food));
                    string text = "";

                    if (food?.def?.ingestible?.ingestCommandString == null ||
                        food.def.ingestible.ingestCommandString == "")
                    {
                        text = ((string)"ConsumeThing".Translate(food.LabelShort, food));
                    }
                    else
                    {
                        text = string.Format(food.def.ingestible.ingestCommandString, food.LabelShort);
                    }

                    FloatMenuOption o = opts.FirstOrDefault(x => x.Label.Contains(text));
                    if (o != null)
                    {
                        opts.Remove(o);
                    }
                }

                //Hide corpse consumption from menus.
                Thing corpse = c.GetThingList(pawn.Map).FirstOrDefault(t => t is Corpse);
                if (corpse != null)
                {
                    string text;
                    if (corpse.def.ingestible.ingestCommandString.NullOrEmpty())
                    {
                        text = "ConsumeThing".Translate(new object[]
                        {
                            corpse.LabelShort
                        });
                    }
                    else
                    {
                        text = string.Format(corpse.def.ingestible.ingestCommandString, corpse.LabelShort);
                    }

                    FloatMenuOption o = opts.FirstOrDefault(x => x.Label.Contains(text));
                    if (o != null)
                    {
                        opts.Remove(o);
                    }
                }

                //Add blood consumption
                Thing bloodItem = c.GetThingList(pawn.Map)
                                  .FirstOrDefault(t => t.def.GetCompProperties <CompProperties_BloodItem>() != null);
                if (bloodItem != null)
                {
                    string text = "";
                    if (bloodItem.def.ingestible.ingestCommandString.NullOrEmpty())
                    {
                        text = "ConsumeThing".Translate(new object[]
                        {
                            bloodItem.LabelShort
                        });
                    }
                    else
                    {
                        text = string.Format(bloodItem.def.ingestible.ingestCommandString, bloodItem.LabelShort);
                    }

                    if (!bloodItem.IsSociallyProper(pawn))
                    {
                        text = text + " (" + "ReservedForPrisoners".Translate() + ")";
                    }

                    FloatMenuOption item5;
                    if (bloodItem.def.IsPleasureDrug && pawn.IsTeetotaler())
                    {
                        item5 = new FloatMenuOption(text + " (" + TraitDefOf.DrugDesire.DataAtDegree(-1).label + ")",
                                                    null);
                    }
                    else if (!pawn.CanReach(bloodItem, PathEndMode.OnCell, Danger.Deadly))
                    {
                        item5 = new FloatMenuOption(text + " (" + "NoPath".Translate() + ")", null);
                    }
                    else
                    {
                        MenuOptionPriority priority =
                            !(bloodItem is Corpse) ? MenuOptionPriority.Default : MenuOptionPriority.Low;
                        item5 = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text, delegate
                        {
                            bloodItem.SetForbidden(false);
                            Job job   = new Job(VampDefOf.ROMV_ConsumeBlood, bloodItem);
                            job.count = BloodUtility.WillConsumeStackCountOf(pawn, bloodItem.def);
                            pawn.jobs.TryTakeOrderedJob(job);
                        }, priority), pawn, bloodItem);
                    }

                    opts.Add(item5);
                }
            }
        }