private void GenerateCarriers(PawnGroupMakerParms parms, PawnGroupMaker groupMaker, List <Thing> wares, Caravan caravan)
        {
            List <Thing>          list    = wares.Where((Thing x) => !(x is Pawn)).ToList();
            int                   i       = 0;
            int                   num     = Mathf.CeilToInt((float)list.Count / 8f);
            PawnKindDef           kind    = groupMaker.carriers.Where((PawnGenOption x) => parms.tile == -1 || Find.WorldGrid[parms.tile].biome.IsPackAnimalAllowed(x.kind.race)).RandomElementByWeight((PawnGenOption x) => x.selectionWeight).kind;
            List <Pawn>           list2   = new List <Pawn>();
            PawnGenerationRequest request = default(PawnGenerationRequest);

            for (int j = 0; j < num; j++)
            {
                PawnKindDef kind2   = kind;
                Faction     faction = parms.faction;
                int         tile    = parms.tile;
                request = new PawnGenerationRequest(kind2, faction, PawnGenerationContext.NonPlayer, tile, forceGenerateNewPawn: false, newborn: false, allowDead: false, allowDowned: false, canGeneratePawnRelations: true, mustBeCapableOfViolence: false, 1f, forceAddFreeWarmLayerIfNeeded: false, allowGay: true, allowFood: true, parms.inhabitants);
                Pawn pawn = PawnGenerator.GeneratePawn(request);
                if (i < list.Count)
                {
                    pawn.inventory.innerContainer.TryAdd(list[i]);
                    i++;
                }
                list2.Add(pawn);

                Find.WorldPawns.PassToWorld(pawn);
                caravan.AddPawn(pawn, false);
            }
            for (; i < list.Count; i++)
            {
                list2.RandomElement().inventory.innerContainer.TryAdd(list[i]);
            }
        }
Beispiel #2
0
        public static List <Pawn> GeneratePawns(PawnGroupMakerParms parms, PawnGroupMaker groupMaker, bool errorOnZeroResults = true)
        {
            var list = new List <Pawn>();

            PawnGroupKindWorker.pawnsBeingGeneratedNow.Add(item: list);

            try
            {
                GeneratePawns(parms: parms, groupMaker: groupMaker, outPawns: list, errorOnZeroResults: errorOnZeroResults);
            }
            catch (Exception arg)
            {
                Log.Error(text: "Exception while generating pawn group: " + arg);

                for (var i = 0; i < list.Count; i++)
                {
                    list[index : i].Destroy(mode : DestroyMode.Vanish);
                }

                list.Clear();
            }
            finally
            {
                PawnGroupKindWorker.pawnsBeingGeneratedNow.Remove(item: list);
            }

            return(list);
        }
        public override float MinPointsToGenerateAnything(PawnGroupMaker groupMaker)
        {
            // NOTE: Just figured out that this would never be used for the
            // Carnival GroupKind. Leaving it here in case I can use it elsewhere.

            return(_DefOf.CarnyTrader.combatPower);
        }
        public static void TryGetRandomPawnGroupMaker(PawnGroupMakerParms parms, out PawnGroupMaker pawnGroupMaker)
        {
            if (parms.faction.def.pawnGroupMakers.NullOrEmpty())
            {
                Log.Error(
                    text: string.Concat("Faction ", parms.faction, " of def ", parms.faction.def, " has no any PawnGroupMakers.")
                    );
            }

            if (parms.seed != null)
            {
                Rand.PushState(replacementSeed: parms.seed.Value);
            }

            IEnumerable <PawnGroupMaker> source =
                from gm in parms.faction.def.pawnGroupMakers
                where gm.kindDef == parms.groupKind && gm.CanGenerateFrom(parms: parms)
                select gm;

            bool result = source.TryRandomElementByWeight(weightSelector: gm => gm.commonality, result: out pawnGroupMaker);

            if (!source.Any())
            {
                Log.Message($"Found no pawn groups fit for purpose");
            }
            if (parms.seed != null)
            {
                Rand.PopState();
            }
        }
        //PawnGroupKindWorker_Trader
        public static void AddQuestGiverTwo(PawnGroupMakerParms parms, PawnGroupMaker groupMaker, Pawn trader,
                                            List <Thing> wares, List <Pawn> outPawns)
        {
            LongEventHandler.QueueLongEvent(() =>
            {
                var pawn = outPawns.FirstOrDefault(x => x.Spawned);
                Map map  = pawn?.MapHeld;
                if (map != null)
                {
                    List <Pawn> newPawnList = map.mapPawns.AllPawnsSpawned.FindAll(x => x.Faction == pawn.Faction && !x.IsPrisoner);
                    var newQuestPawn        = RimQuestUtility.GetNewQuestGiver(outPawns);
                    if (newQuestPawn?.Faction == null)
                    {
                        return;
                    }

                    var questPawns = Find.World.GetComponent <RimQuestTracker>().questPawns;
                    if (!questPawns.Any(x => x.pawn == newQuestPawn))
                    {
                        var questPawn = new QuestPawn(newQuestPawn);
                        if (questPawn != null)
                        {
                            questPawns.Add(questPawn);
                        }
                    }
                }
            }, "RQ_LoadingScreen".Translate(), true, null);
        }
        public static void Prefix(PawnGroupMakerParms parms, ref PawnGroupMaker pawnGroupMaker)
        {
            Faction faction = parms.faction;
            HiveFactionEvolutionTracker evolutionTracker = Find.World.GetComponent <HiveFactionEvolutionTracker>();

            if (faction != null)
            {
                HiveFactionExtension hive = faction.def.GetModExtension <HiveFactionExtension>();
                if (evolutionTracker != null && hive != null)
                {
                    if (evolutionTracker.HiveFactionStages.TryGetValue(faction.ToString(), out int stage))
                    {
                        if (parms.seed != null)
                        {
                            Rand.PushState(parms.seed.Value);
                        }
                        if (!hive.CurStage.pawnGroupMakers.NullOrEmpty())
                        {
                            string li = string.Empty;
                            //    Log.Message("TryGetRandomPawnGroupMaker HiveFaction using pawnGroupMaker from Stage: " + stage);
                        }
                        bool result = (from gm in hive.CurStage.pawnGroupMakers ?? parms.faction.def.pawnGroupMakers
                                       where gm.kindDef == parms.groupKind && gm.CanGenerateFrom(parms)
                                       select gm).TryRandomElementByWeight((PawnGroupMaker gm) => gm.commonality, out pawnGroupMaker);
                        if (parms.seed != null)
                        {
                            Rand.PopState();
                        }
                        //    Log.Message("TryGetRandomPawnGroupMaker HiveFaction Stage: " + stage + " pawnGroupMaker: " + pawnGroupMaker.kindDef);
                    }
                }
            }
        }
 public override bool CanGenerateFrom(PawnGroupMakerParms parms, PawnGroupMaker groupMaker)
 {
     return(groupMaker.kindDef == _DefOf.Carnival &&
            parms.faction.IsCarnival() &&
            MinPointsToGenerateAnything(groupMaker) < parms.points &&
            (parms.tile == -1 ||
             groupMaker.carriers.Any((PawnGenOption x) => Find.WorldGrid[parms.tile].biome.IsPackAnimalAllowed(x.kind.race))));
 }
Beispiel #8
0
        public static void MinPointsTest(PawnGroupKindWorker_Normal __instance, PawnGroupMaker groupMaker)
        {
//            if (groupMaker?.options?.Count == null ||
//                groupMaker.options.Count <= 0)
//            {
//                Log.Message("No options available.");
//            }
//            foreach (var x in groupMaker.options)
//            {
//                Log.Message(x.kind.defName + " " + x.kind.isFighter.ToString() +  " " + x.Cost);
//            }
        }
Beispiel #9
0
 private static void AddPawn(this PawnGroupMaker pgm, PawnGenOption pgo, bool isTrader = false)
 {
     if (pgo.kind == null)
     {
         return;
     }
     ;
     if (isTrader)
     {
         pgm.guards.Add(pgo);
         return;
     }
     pgm.options.Add(pgo);
 }
        /* Private Methods */


        private Pawn GenerateVendor(PawnGroupMakerParms parms, PawnGroupMaker groupMaker, TraderKindDef traderKind, bool subtractPoints)
        {
            if (subtractPoints)
            {
                if (parms.points < _DefOf.CarnyTrader.combatPower * 2)
                {
                    return(null);
                }
                else
                {
                    parms.points -= _DefOf.CarnyTrader.combatPower * 2;
                }
            }

            // Generate new vendor
            PawnGenerationRequest request = new PawnGenerationRequest(
                _DefOf.CarnyTrader,
                parms.faction,
                PawnGenerationContext.NonPlayer,
                parms.tile,
                false,
                false,
                false,
                false,
                true,
                false,
                1f,
                true, // Force free warm layers if needed
                true,
                true,
                parms.inhabitants,
                false,
                null, // Consider adding predicate for backstory here
                null,
                null,
                null,
                null,
                null
                );

            var vendor = PawnGenerator.GeneratePawn(request);

            vendor.mindState.wantsToTradeWithColony = true;

            PawnComponentsUtility.AddAndRemoveDynamicComponents(vendor, true);
            vendor.trader.traderKind = traderKind;

            return(vendor);
        }
        private bool TryGetRandomPawnGroupMaker(PawnGroupMakerParms parms, out PawnGroupMaker pawnGroupMaker)
        {
            if (parms.seed.HasValue)
            {
                Rand.PushState(parms.seed.Value);
            }
            IEnumerable <PawnGroupMaker> source = parms.faction.def.pawnGroupMakers.Where((PawnGroupMaker gm) => gm.kindDef == parms.groupKind && gm.CanGenerateFrom(parms));
            bool result = source.TryRandomElementByWeight((PawnGroupMaker gm) => gm.commonality, out pawnGroupMaker);

            if (parms.seed.HasValue)
            {
                Rand.PopState();
            }
            return(result);
        }
 private static void Postfix(PawnGroupMakerParms parms, PawnGroupMaker groupMaker, Pawn trader, List <Thing> wares, ref List <Pawn> outPawns)
 {
     Log.Message("Postfix 3");
     if (Rand.Chance(0.8f) && outPawns.Count > 0)
     {
         var candidates = outPawns.Where(x => x.def.race.Humanlike &&
                                         x.AllComps.Where(y => y is CompQuestGiver).Count() == 0);
         if (candidates.Count() > 0)
         {
             Pawn pawn      = candidates.RandomElement();
             var  questComp = Current.Game.GetComponent <QuestTracker>();
             questComp.CreateQuestGiver(pawn);
         }
     }
 }
        /* Validation Private Methods */



        private bool ValidateCarriers(PawnGroupMaker groupMaker)
        {
            PawnGenOption pawnGenOption = groupMaker.carriers.FirstOrDefault((PawnGenOption x) => !x.kind.RaceProps.packAnimal);

            if (pawnGenOption != null)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Cannot generate arriving carnival for ",
                    "Carn_Faction_Roaming",
                    " because there is a pawn kind (",
                    pawnGenOption.kind.LabelCap,
                    ") who is not a carrier but is in a carriers list."
                }));
                return(false);
            }

            return(true);
        }
        private bool ValidateTradersList(PawnGroupMaker groupMaker)
        {
            // Returns false if there is an error in PawnGenOption XML (in Faction def)
            PawnGenOption pawnGenOption = groupMaker.traders.FirstOrDefault((PawnGenOption x) => !x.kind.trader);

            if (pawnGenOption != null)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Cannot generate arriving carnival for ",
                    "Carn_Faction_Roaming",
                    " because there is a pawn kind (",
                    pawnGenOption.kind.LabelCap,
                    ") who is not a trader but is in a traders list."
                }));
                return(false);
            }

            return(true);
        }
Beispiel #15
0
 private static PawnGroupMaker AddPawnKindsToFactions(PawnGroupMaker pgm, string label)
 {
     // groups can be either an options or a guards for whatever reason, so check for both.
     PawnGenOption[] options = pgm.options.ToArray();
     for (int i = 0; i < options.Length; i++)
     {
         PawnGenOption pgo = MakePawnGenOption(options[i], label);
         if (pgo != null)
         {
             pgm.AddPawn(pgo, false);
         }
     }
     PawnGenOption[] guards = pgm.guards.ToArray();
     for (int j = 0; j < guards.Length; j++)
     {
         PawnGenOption pgo = MakePawnGenOption(guards[j], label);
         if (pgo != null)
         {
             pgm.AddPawn(pgo, true);
         }
     }
     return(pgm);
 }
Beispiel #16
0
 public override void PostWorldGenerate()
 {
     if (AMAMod.settings.ForceRelations)
     {
         int        i           = 0;
         Faction    faction     = null;
         FactionDef factionDef  = null;
         ThingDef   factionRace = null;
         Faction    player      = Faction.OfPlayer;
         FactionDef playerDef   = player.def;
         ThingDef   playerRace  = playerDef.basicMemberKind.race;
         //    Log.Message(string.Format("PWG Player: {0}\nDef: {1}\nRace: {2}", player, playerDef, playerRace));
         base.PostWorldGenerate();
         foreach (var f in Find.FactionManager.AllFactionsListForReading.FindAll(x => !x.IsPlayer && !x.def.permanentEnemy))
         {
             faction     = null;
             factionDef  = null;
             factionRace = null;
             faction     = f;
             factionDef  = faction.def;
             factionRace = factionDef.basicMemberKind?.race;
             if (factionDef.basicMemberKind == null)
             {
                 //    Log.Message(string.Format("basicMemberKind: Missing, checking PGM for {0} def: {1}", f, factionDef));
                 if (!factionDef.pawnGroupMakers.NullOrEmpty())
                 {
                     //    Log.Message(string.Format("PGM: Found, checking options for {0} def: {1}", f, factionDef));
                     PawnGroupMaker maker = factionDef.pawnGroupMakers.RandomElement();
                     if (!maker.options.NullOrEmpty())
                     {
                         //    Log.Message(string.Format("options: Found, checking for {0} def: {1}", f, factionDef));
                         PawnGenOption genOption = maker.options.RandomElement();
                         if (genOption != null)
                         {
                             factionRace = genOption.kind.race;
                             //    Log.Message(string.Format("Race: {2}, checking for {0} def: {1}", f, factionDef, factionRace));
                         }
                         else
                         {
                             //    Log.Message(string.Format("Race: Not Found for {0} def: {1}", f, factionDef));
                         }
                     }
                     else
                     {
                         //    Log.Message(string.Format("options: Not Found for {0} def: {1}", f, factionDef));
                     }
                 }
                 else
                 {
                     //    Log.Message(string.Format("PGM: Missing for {0}", factionDef));
                 }
             }
             if (factionRace != null)
             {
                 //    Log.Message(string.Format("Race: {0}", factionRace));
                 if (factionRace != playerRace)
                 {
                     if ((factionDef.defName.Contains("OG_Mechanicus_") || factionDef.defName.Contains("OG_Militarum_") || factionDef.defName.Contains("OG_Astartes_") || factionDef.defName.Contains("OG_Sororitas_")) && (playerRace.defName.Contains("Human") || (playerRace.defName.Contains("OG_Mechanicus_") || playerRace.defName.Contains("OG_Militarum_") || playerRace.defName.Contains("OG_Astartes_") || playerRace.defName.Contains("OG_Sororitas_"))) && !playerRace.defName.Contains("OG_Chaos"))
                     {
                         //    Log.Message(string.Format("Imperial Faction {0}: {1} should be friendly to {2}", f, factionDef, player));
                         if (f.GoodwillWith(player) < 0)
                         {
                             player.TrySetRelationKind(f, FactionRelationKind.Ally, false);
                         }
                     }
                     else if ((factionDef.defName.Contains("OG_Eldar_") && (playerRace.defName.Contains("Alien_Eldar") || playerRace.defName.Contains("OG_Eldar_"))))
                     {
                         //    Log.Message(string.Format("Eldar faction{0}: {1} should be friendly to {2}: {3}", f, factionDef, player, playerDef));
                         if (f.GoodwillWith(player) < 0)
                         {
                             player.TrySetRelationKind(f, FactionRelationKind.Ally, false);
                         }
                     }
                     else if ((factionDef.defName.Contains("OG_Ork_")) && (playerRace.defName.Contains("Alien_Ork") || playerRace.defName.Contains("Alien_Grot") || playerRace.defName.Contains("OG_Ork_") || playerRace.defName.Contains("OG_Grot_")))
                     {
                         //    Log.Message(string.Format("Ork faction {0}: {1} should be friendly to {2}: {3}", f, f.def, player, playerDef));
                         if (f.GoodwillWith(player) < 0)
                         {
                             player.TrySetRelationKind(f, FactionRelationKind.Neutral, false);
                         }
                     }
                     else if ((factionDef.defName.Contains("OG_Tau_") || factionDef.defName.Contains("OG_Kroot_") || factionDef.defName.Contains("OG_Vespid_")) && (playerRace.defName.Contains("Alien_Tau") || playerRace.defName.Contains("Alien_Kroot") || playerRace.defName.Contains("OG_Tau_") || playerRace.defName.Contains("OG_Kroot_")))
                     {
                         //    Log.Message(string.Format("Tau faction {0}: {1} should be friendly to {2}: {3}", f, factionDef, player, playerDef));
                         if (f.GoodwillWith(player) < 0)
                         {
                             player.TrySetRelationKind(f, FactionRelationKind.Ally, false);
                         }
                     }
                     else if ((factionDef.defName.Contains("OG_Chaos_")) && (playerRace.defName.Contains("OG_Chaos")))
                     {
                         //    Log.Message(string.Format("Chaos faction {0}: {1} should be friendly to {2}: {3}", f, factionDef, player, playerDef));
                         if (f.GoodwillWith(player) < 0)
                         {
                             player.TrySetRelationKind(f, FactionRelationKind.Neutral, false);
                         }
                     }
                     else
                     {
                         //    Log.Message(string.Format("{0}: {1} should be hostile to {2}: {3}", f, factionDef, player, playerDef));
                         player.TrySetRelationKind(f, FactionRelationKind.Hostile, false);
                     }
                 }
             }
         }
     }
 }
Beispiel #17
0
        static bool Prefix(ref PawnGroupKindWorker_Trader __instance, ref Pawn __result, PawnGroupMakerParms parms, PawnGroupMaker groupMaker, TraderKindDef traderKind)
        {
            if (parms.faction == FactionColonies.getPlayerColonyFaction())
            {
                List <PawnKindDef> list = new List <PawnKindDef>();
                foreach (ThingDef def in Find.World.GetComponent <FactionFC>().raceFilter.AllowedThingDefs)
                {
                    list.Add(def.race.AnyPawnKind);
                }

                Pawn pawn = PawnGenerator.GeneratePawn(new PawnGenerationRequest(list.RandomElement(), parms.faction, PawnGenerationContext.NonPlayer, parms.tile, false, false, false, false, true, false, 1f, false, true, true, true, parms.inhabitants, false, false, false, 0f, null, 1f, null, null, null, null, null, null, null, null, null, null, null, null));
                pawn.mindState.wantsToTradeWithColony = true;
                PawnComponentsUtility.AddAndRemoveDynamicComponents(pawn, true);
                pawn.trader.traderKind = traderKind;
                parms.points          -= pawn.kindDef.combatPower;
                __result = pawn;


                return(false);
            }
            else
            {
                return(true);
            }
        }
Beispiel #18
0
 private static bool <PawnGroupGenSampled> m__2(PawnGroupMaker x)
 {
     return(x.kindDef == PawnGroupKindDefOf.Combat);
 }
Beispiel #19
0
            private static bool Prefix(PawnGroupMakerParms parms, PawnGroupMaker groupMaker, Pawn trader, List <Thing> wares, List <Pawn> outPawns)
            {
                Func <Thing, float> massTotaler = t => t.stackCount * t.GetStatValue(StatDefOf.Mass, true);

                List <Thing> list = wares.Where(t => !(t is Pawn)).ToList();

                list.SortByDescending(massTotaler);

                float ttlMassThings = list.Sum(massTotaler);
                float ttlCapacity   = 0f;
                float ttlBodySize   = 0f;
                int   numCarriers   = 0;

                IEnumerable <PawnGenOption> carrierKinds = groupMaker.carriers.Where(p => {
                    if (parms.tile != -1)
                    {
                        return(Find.WorldGrid[parms.tile].biome.IsPackAnimalAllowed(p.kind.race));
                    }
                    return(true);
                });

                PawnKindDef kind = carrierKinds.RandomElementByWeight(x => x.selectionWeight).kind;

                // No slow or small juveniles
                Predicate <Pawn> validator = (p =>
                                              p.ageTracker.CurLifeStage.bodySizeFactor >= 1 &&
                                              p.GetStatValue(StatDefOf.MoveSpeed, true) >= p.kindDef.race.GetStatValueAbstract(StatDefOf.MoveSpeed)
                                              );

                // 50/50 chance of uniform carriers (like vanilla) or mixed carriers
                bool mixedCarriers = Rand.RangeInclusive(0, 1) == 1;

                // Generate all of the carrier pawns (empty).  Either we spawn as many pawns as we need to cover
                // 120% of the weight of the items, or enough pawns before it seems "unreasonable" based on body
                // size.
                for (; ttlCapacity < ttlMassThings * 1.2 && ttlBodySize < 20; numCarriers++)
                {
                    PawnGenerationRequest request = new PawnGenerationRequest(
                        kind:             kind,
                        faction:          parms.faction,
                        tile:             parms.tile,
                        inhabitant:       parms.inhabitants,
                        validatorPreGear: validator
                        );
                    Pawn pawn = PawnGenerator.GeneratePawn(request);
                    outPawns.Add(pawn);

                    ttlCapacity += MassUtility.Capacity(pawn);
                    // Still can't have 100 chickenmuffalos.  That might slow down some PCs.
                    ttlBodySize += Mathf.Max(pawn.BodySize, 0.5f);

                    if (mixedCarriers)
                    {
                        kind = carrierKinds.RandomElementByWeight(x => x.selectionWeight).kind;
                    }
                }

                // Add items (in descending order of weight) to randomly chosen pack animals.  This isn't the most
                // efficient routine, as we're trying to be a bit random.  If I was trying to be efficient, I would
                // use something like SortByDescending(p.Capacity) against the existing thing list.
                foreach (Thing thing in list)
                {
                    List <Pawn> validPawns = outPawns.FindAll(p => !MassUtility.WillBeOverEncumberedAfterPickingUp(p, thing, thing.stackCount));

                    if (validPawns.Count() != 0)
                    {
                        validPawns.RandomElement().inventory.innerContainer.TryAdd(thing, true);
                    }
                    else if (thing.stackCount > 1)
                    {
                        // No carrier can handle the full stack; split it up
                        int countLeft = thing.stackCount;
                        int c         = 0; // safety counter (while loops can be dangerous)
                        while (countLeft > 0)
                        {
                            validPawns = outPawns.FindAll(p => MassUtility.CountToPickUpUntilOverEncumbered(p, thing) >= 1);
                            if (validPawns.Count() != 0 && c < thing.stackCount)
                            {
                                Pawn pawn       = validPawns.RandomElement();
                                int  countToAdd = Mathf.Min(MassUtility.CountToPickUpUntilOverEncumbered(pawn, thing), countLeft);
                                countLeft -= pawn.inventory.innerContainer.TryAdd(thing, countToAdd, true);
                            }
                            else
                            {
                                // Either no carrier can handle a single item, or we're just in some bad while loop breakout.  In
                                // any case, force it in, evenly split among all carriers.
                                int splitCount = Mathf.FloorToInt(countLeft / outPawns.Count());
                                if (splitCount > 0)
                                {
                                    outPawns.ForEach(p => p.inventory.innerContainer.TryAdd(thing, splitCount, true));
                                    countLeft -= splitCount * outPawns.Count();
                                }

                                // Give the remainer to the ones with space (one at a time)
                                while (countLeft > 0)
                                {
                                    validPawns = new List <Pawn>(outPawns);
                                    validPawns.SortByDescending(p => MassUtility.FreeSpace(p));
                                    validPawns.First().inventory.innerContainer.TryAdd(thing, 1, true);
                                    countLeft--;
                                }
                                break;
                            }
                            c++;
                        }
                    }
                    else
                    {
                        // No way to split it; force it in
                        validPawns = new List <Pawn>(outPawns);
                        validPawns.SortByDescending(p => MassUtility.FreeSpace(p));
                        validPawns.First().inventory.innerContainer.TryAdd(thing, true);
                    }
                }

                // Always skip the original method
                return(false);
            }
Beispiel #20
0
        public static void GeneratePawns(PawnGroupMakerParms parms, PawnGroupMaker groupMaker, List <Pawn> outPawns, bool errorOnZeroResults = true)
        {
            bool canBringFood = parms.raidStrategy?.pawnsCanBringFood ?? true;

            // 15.08.2021 RW1.3 added total points parameter to .CanUsePawn
            // For now just using parms.points however unsure if this will mess other things up
            Predicate <Pawn> postGear = parms.raidStrategy == null
                        ? null
                        : new Predicate <Pawn>(p => parms.raidStrategy.Worker.CanUsePawn(parms.points, p, otherPawns: outPawns));

            var madeOnePawnIncap = false;

            PawnGenUtility.cachedConvertedPawnKindDefs = new Dictionary <string, PawnKindDef>();

            foreach (PawnGenOption pawnGenOption in SolarRaidGroupMaker.ChoosePawnGenByConstraint(
                         pointsTotal: parms.points,
                         options: groupMaker.options,
                         groupParms: parms
                         ))
            {
                PawnKindDef      kind              = pawnGenOption.kind;
                Faction          faction           = parms.faction;
                int              tile              = parms.tile;
                bool             allowFood         = canBringFood;
                bool             inhabitants       = parms.inhabitants;
                Predicate <Pawn> validatorPostGear = postGear;

                var request = new PawnGenerationRequest(
                    kind: PawnGenUtility.ConvertDefAndStoreOld(original: kind),
                    faction: faction,
                    context: PawnGenerationContext.NonPlayer,
                    tile: tile,
                    forceGenerateNewPawn: false,
                    newborn: false,
                    allowDead: false,
                    allowDowned: false,
                    canGeneratePawnRelations: true,
                    mustBeCapableOfViolence: true,
                    colonistRelationChanceFactor: 1f,
                    forceAddFreeWarmLayerIfNeeded: true,
                    allowGay: true,
                    allowFood: allowFood,
                    inhabitant: inhabitants,
                    certainlyBeenInCryptosleep: false,
                    forceRedressWorldPawnIfFormerColonist: false,
                    worldPawnFactionDoesntMatter: false,
                    validatorPreGear: pa => !pa.skills.GetSkill(skillDef: Defs_Rimworld.MeleeSkill).TotallyDisabled,
                    validatorPostGear: validatorPostGear,
                    minChanceToRedressWorldPawn: null,
                    fixedBiologicalAge: null,
                    fixedChronologicalAge: null,
                    fixedGender: null,
                    fixedMelanin: null,
                    fixedLastName: null
                    );

                Pawn pawn = PawnGenerator.GeneratePawn(request: request);

                if (parms.forceOneIncap && !madeOnePawnIncap)
                {
                    pawn.health.forceIncap           = true;
                    pawn.mindState.canFleeIndividual = false;
                    madeOnePawnIncap = true;
                }

                PawnFinaliser(pawn: pawn);
                outPawns.Add(item: pawn);
            }
        }
        private IEnumerable <Pawn> GenerateCarriers(PawnGroupMakerParms parms, PawnGroupMaker groupMaker, List <Thing> wares)
        {
            var carrierList = new List <Pawn>();

            var carrierKind = (from x in groupMaker.carriers
                               where parms.tile == -1 ||
                               Find.WorldGrid[parms.tile].biome.IsPackAnimalAllowed(x.kind.race)
                               select x).RandomElementByWeight(o => o.selectionWeight).kind;

            var waresSansPawns = new List <Thing>();
            var numCarriers    = 1;

            if (!wares.NullOrEmpty())
            {
                var baseCapacity = carrierKind.RaceProps.baseBodySize * 34f; // Leaving some space for silvah, original calculation is 35f
                var totalWeight  = 0f;

                for (int j = wares.Count - 1; j > -1; j--)
                {
                    var thing = wares[j];
                    if (thing is Pawn)
                    {
                        continue;
                    }

                    var mass = thing.Mass();

                    if (thing.stackCount == 1 && mass > baseCapacity)
                    {
                        if (Prefs.DevMode)
                        {
                            Log.Warning("[Carnivale] "
                                        + thing
                                        + " is too big for any carrier and will be removed from wares. mass="
                                        + mass
                                        + ", "
                                        + carrierKind.label
                                        + " capacity="
                                        + baseCapacity
                                        );
                        }
                        wares.RemoveAt(j);
                        continue;
                    }

                    if (thing.def.stackLimit > 1)
                    {
                        while (thing.stackCount >= 2 && mass > baseCapacity)
                        {
                            thing.stackCount /= 2;
                            mass              = thing.Mass();

                            if (Prefs.DevMode)
                            {
                                Log.Message("\t[Carnivale] " + thing.LabelShort + " was to heavy for any carrier. Reducing its stack count to " + thing.stackCount + " and trying again.");
                            }
                        }

                        if (mass > baseCapacity)
                        {
                            if (Prefs.DevMode)
                            {
                                Log.Warning("[Carnivale] "
                                            + thing.LabelShort
                                            + " is too heavy for any carrier and will be removed from wares. mass="
                                            + mass
                                            + ", stackCount="
                                            + thing.stackCount
                                            + ", carrierKind="
                                            + carrierKind.label
                                            + ", capacity="
                                            + baseCapacity
                                            );
                            }
                            wares.RemoveAt(j);
                            continue;
                        }
                    }

                    totalWeight += mass;
                    waresSansPawns.Add(thing);
                }

                numCarriers = Mathf.CeilToInt(totalWeight / baseCapacity);
            }
            else
            {
                var silver = ThingMaker.MakeThing(ThingDefOf.Silver);
                silver.stackCount = 100;
                waresSansPawns.Add(silver);
            }

            int i = 0;

            for (int j = 0; j < numCarriers; j++)
            {
                // Generate carrier
                PawnGenerationRequest request = new PawnGenerationRequest(
                    carrierKind,
                    parms.faction,
                    PawnGenerationContext.NonPlayer,
                    parms.tile,
                    false,
                    false,
                    false,
                    false,
                    true,
                    false,
                    1f,
                    false,
                    true,
                    true,
                    parms.inhabitants,
                    false,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null
                    );

                var carrier = PawnGenerator.GeneratePawn(request);

                if (i < waresSansPawns.Count)
                {
                    // Add initial few items to carrier
                    if (carrier.inventory.innerContainer.TryAdd(waresSansPawns[i], true))
                    {
                        i++;
                    }
                }

                carrierList.Add(carrier);
                yield return(carrier);
            }

            // Finally, fill up all the carriers' inventories
            while (i < waresSansPawns.Count)
            {
                var thing = waresSansPawns[i];
                var mass  = thing.Mass();

                var carrier = carrierList.MaxBy(c => MassUtility.FreeSpace(c));
                if (thing.stackCount > 1 && !carrier.HasSpaceFor(thing))
                {
                    while (thing.stackCount >= 2 && mass > MassUtility.FreeSpace(carrier))
                    {
                        thing.stackCount /= 2;
                        mass              = thing.Mass();

                        if (Prefs.DevMode)
                        {
                            Log.Message("\t[Carnivale] " + thing.LabelShort + " was to heavy for any carrier. Reducing its stack count to " + thing.stackCount + " and trying again.");
                        }
                    }
                }

                if (carrier.inventory.innerContainer.TryAdd(thing))
                {
                    i++;
                }
                else
                {
                    if (Prefs.DevMode)
                    {
                        Log.Warning("[Carnivale] "
                                    + thing.LabelShort
                                    + " is too heavy for any carrier and will be removed from wares. mass="
                                    + mass
                                    + ", stackCount="
                                    + thing.stackCount
                                    + ", carrierKind="
                                    + carrierKind.label
                                    + ", freeSpace="
                                    + MassUtility.FreeSpace(carrier)
                                    );
                    }

                    wares.RemoveAt(i);
                }
            }

            if (i == waresSansPawns.Count)
            {
                yield break;
            }

            var remainingMass      = waresSansPawns.Sum(w => w.Mass());
            var remainingFreeSpace = carrierList.Sum(c => MassUtility.FreeSpace(c));

            if (Prefs.DevMode)
            {
                Log.Warning("[Carnivale] Could not fit all wares in carriers. remainingMass=" + remainingMass + ", remainingFreeSpace=" + remainingFreeSpace);
            }

            while (i < waresSansPawns.Count)
            {
                var thing = waresSansPawns[i];

                // Remove things that could not fit for whatever reason
                if (Prefs.DevMode)
                {
                    Log.Warning("\t[Carnivale] removing " + thing);
                }
                wares.Remove(waresSansPawns[i]);

                i++;
            }
        }
        protected override void GeneratePawns(PawnGroupMakerParms parms, PawnGroupMaker groupMaker, List <Pawn> outPawns, bool errorOnZeroResults = true)
        {
            genderValidator = null;

            // Validation steps
            if (!CanGenerateFrom(parms, groupMaker) || !ValidateTradersList(groupMaker) || !ValidateCarriers(groupMaker))
            {
                if (errorOnZeroResults)
                {
                    Log.Error("Cannot generate carnival caravan for " + parms.faction + ". parms=" + parms);
                }
                return;
            }
            // End validation steps


            // Restrict gender of entertainers if it is in the name
            if (parms.faction.Name.EndsWith("Boys"))
            {
                genderValidator = delegate(Pawn p)
                {
                    return(p.Is(CarnivalRole.Entertainer, false) && p.gender == Gender.Male);
                };
            }
            else if (parms.faction.Name.EndsWith("Girls") ||
                     parms.faction.Name.EndsWith("Gals"))
            {
                genderValidator = delegate(Pawn p)
                {
                    return(p.Is(CarnivalRole.Entertainer, false) && p.gender == Gender.Female);
                };
            }


            // New approach

            // Spawn manager (costless)
            outPawns.Add(parms.faction.leader);

            // Generate vendors (first is costless)
            var allWares   = new List <Thing>();
            int numCarnies = 0;
            int maxVendors = Mathf.Clamp(groupMaker.traders.First().selectionWeight, 1, MaxVendors);

            for (int i = 0; i < maxVendors; i++)
            {
                TraderKindDef traderKind = null;

                int t = i % 3;
                switch (t)
                {
                case 0:
                    traderKind = _DefOf.Carn_Trader_Food;
                    break;

                case 1:
                    traderKind = _DefOf.Carn_Trader_Surplus;
                    break;

                case 2:
                    traderKind = _DefOf.Carn_Trader_Curios;
                    break;

                default:
                    traderKind = _DefOf.Carn_Trader_Food;
                    Log.Error("PawnGroupKindWorker_Carnival reached a bad place in code.");
                    break;
                }

                // Subtracts points, first costless:
                var vendor = GenerateVendor(parms, groupMaker, traderKind, i > 0);
                if (vendor != null)
                {
                    outPawns.Add(vendor);
                    numCarnies++;
                }
                else
                {
                    break;
                }


                // Generate wares
                var waresParms = default(ItemCollectionGeneratorParams);
                waresParms.traderDef  = traderKind;
                waresParms.forTile    = parms.tile;
                waresParms.forFaction = parms.faction;
                waresParms.validator  = delegate(ThingDef def)
                {
                    if (def.stackLimit > 1)
                    {
                        return(def.statBases.GetStatValueFromList(StatDefOf.Mass, 1f) * (def.stackLimit / 3f) < 68f);
                    }
                    else
                    {
                        return(def.statBases.GetStatValueFromList(StatDefOf.Mass, 1f) < 68f);
                    }
                };

                allWares.AddRange(ItemCollectionGeneratorDefOf.TraderStock.Worker.Generate(waresParms));

                // Generate guards for each trader
                foreach (var guard in GenerateGroup(parms, groupMaker.guards, i > 0))
                {
                    outPawns.Add(guard);
                }

                // Generate carnies for each trader
                foreach (var carny in GenerateGroup(parms, groupMaker.options, i > 0))
                {
                    if (numCarnies++ > MaxCarnies)
                    {
                        break;
                    }
                    outPawns.Add(carny);
                }
            }

            // Spawn pawns that are for sale (if any)
            foreach (Pawn sellable in GetPawnsFromWares(parms, allWares))
            {
                outPawns.Add(sellable);
            }

            // Generate carriers
            outPawns.AddRange(
                GenerateCarriers(parms, groupMaker, allWares)       // carriers w/ traders' wares
                .Concat(GenerateCarriers(parms, groupMaker, null))  // carrier w/ 100 silver
                );
        }
Beispiel #23
0
        private void DrawFactionButtons(Rect inRect, int buttonSize)         //Used to draw a list of buttons from the 'buttons' list
        {
            Text.Anchor = TextAnchor.MiddleCenter;
            Text.Font   = GameFont.Small;
            for (int i = 0; i < buttons.Count; i++)
            {
                if (Widgets.ButtonText(new Rect(140, 110 + ((buttonSize + 5) * i), 170, buttonSize), buttons[i]))
                {
                    if (buttons[i] == "FCOverview".Translate())
                    {                     //if click trade policy button
                                          //Log.Message(buttons[i]);
                        Log.Message("Success");
                        Find.WindowStack.Add(new FCWindow_Overview());
                    }


                    if (buttons[i] == "Military".Translate())
                    {
                        if (FactionColonies.getPlayerColonyFaction() == null)
                        {
                            Messages.Message(new Message("NoFactionForMilitary".Translate(), MessageTypeDefOf.RejectInput));
                        }
                        else
                        {
                            Find.WindowStack.Add(new militaryCustomizationWindowFC());
                        }
                    }

                    if (buttons[i] == "Actions".Translate())
                    {
                        List <FloatMenuOption> list = new List <FloatMenuOption>();

                        list.Add(new FloatMenuOption("TaxDeliveryMap".Translate(), delegate
                        {
                            List <FloatMenuOption> list2 = new List <FloatMenuOption>();


                            list2.Add(new FloatMenuOption("SetMap".Translate(), delegate
                            {
                                List <FloatMenuOption> settlementList = new List <FloatMenuOption>();

                                foreach (Map map in Find.Maps)
                                {
                                    if (map.IsPlayerHome)
                                    {
                                        settlementList.Add(new FloatMenuOption(map.Parent.LabelCap, delegate
                                        {
                                            faction.taxMap = map;
                                            Find.LetterStack.ReceiveLetter("Map Set!", "The tax delivery map has been set to the player colony of " + map.Parent.LabelCap + ".\n All taxes and other goods will be delivered there", LetterDefOf.NeutralEvent);
                                        }
                                                                               ));
                                    }
                                }

                                if (settlementList.Count == 0)
                                {
                                    settlementList.Add(new FloatMenuOption("No valid settlements to use.", null));
                                }

                                FloatMenu floatMenu2            = new FloatMenu(settlementList);
                                floatMenu2.vanishIfMouseDistant = true;
                                Find.WindowStack.Add(floatMenu2);
                            }));

                            FloatMenu floatMenu            = new FloatMenu(list2);
                            floatMenu.vanishIfMouseDistant = true;
                            Find.WindowStack.Add(floatMenu);
                        }));

                        list.Add(new FloatMenuOption("SetCapital".Translate(), delegate
                        {
                            faction.setCapital();
                        }));

                        list.Add(new FloatMenuOption("ActivateResearch".Translate(), delegate
                        {
                            faction.updateDailyResearch();
                        }));

                        list.Add(new FloatMenuOption("ResearchLevel".Translate(), delegate
                        {
                            Messages.Message("CurrentResearchLevel".Translate(faction.techLevel.ToString(), faction.returnNextTechToLevel()), MessageTypeDefOf.NeutralEvent);
                        }));

                        if (faction.hasPolicy(FCPolicyDefOf.technocratic))
                        {
                            list.Add(new FloatMenuOption("FCSendResearchItems".Translate(), delegate
                            {
                                if (Find.ColonistBar.GetColonistsInOrder().Count > 0)
                                {
                                    Pawn playerNegotiator = Find.ColonistBar.GetColonistsInOrder()[0];
                                    //Log.Message(playerNegotiator.Name + " Negotiator");

                                    FCTrader_Research trader = new FCTrader_Research();

                                    Find.WindowStack.Add(new Dialog_Trade(playerNegotiator, trader));
                                }
                                else
                                {
                                    Log.Message("Where are all the colonists?");
                                }
                            }));
                        }

                        if (faction.hasPolicy(FCPolicyDefOf.feudal))
                        {
                            list.Add(new FloatMenuOption("FCRequestMercenary".Translate(), delegate
                            {
                                if (faction.traitFeudalBoolCanUseMercenary)
                                {
                                    faction.traitFeudalBoolCanUseMercenary   = false;
                                    faction.traitFeudalTickLastUsedMercenary = Find.TickManager.TicksGame;
                                    List <PawnKindDef> listKindDef           = new List <PawnKindDef>();
                                    foreach (ThingDef def in Find.World.GetComponent <FactionFC>().raceFilter.AllowedThingDefs)
                                    {
                                        listKindDef.Add(def.race.AnyPawnKind);
                                    }
                                    PawnGroupMaker groupMaker             = FactionColonies.getPlayerColonyFaction().def.pawnGroupMakers.RandomElement();
                                    PawnGroupMakerParms group             = new PawnGroupMakerParms();
                                    group.groupKind                       = groupMaker.kindDef;
                                    group.faction                         = FactionColonies.getPlayerColonyFaction();
                                    group.dontUseSingleUseRocketLaunchers = true;
                                    group.generateFightersOnly            = true;
                                    group.points = 2000;

                                    group.raidStrategy = RaidStrategyDefOf.ImmediateAttackFriendly;


                                    PawnKindDef pawnkind = new PawnKindDef();
                                    PawnKindDef kind     = groupMaker.GeneratePawns(group).RandomElement().kindDef;
                                    pawnkind             = listKindDef.RandomElement();

                                    pawnkind.techHediffsTags            = kind.techHediffsTags;
                                    pawnkind.apparelTags                = kind.apparelTags;
                                    pawnkind.isFighter                  = kind.isFighter;
                                    pawnkind.combatPower                = kind.combatPower;
                                    pawnkind.gearHealthRange            = kind.gearHealthRange;
                                    pawnkind.weaponTags                 = kind.weaponTags;
                                    pawnkind.apparelMoney               = kind.apparelMoney;
                                    pawnkind.weaponMoney                = kind.weaponMoney;
                                    pawnkind.apparelAllowHeadgearChance = kind.apparelAllowHeadgearChance;
                                    pawnkind.techHediffsMoney           = kind.techHediffsMoney;
                                    pawnkind.label = kind.label;

                                    Pawn pawn = PawnGenerator.GeneratePawn(new PawnGenerationRequest(pawnkind, Find.FactionManager.OfPlayer, PawnGenerationContext.NonPlayer, -1, false, false, false, false, true, false, 20f));


                                    IncidentParms parms = new IncidentParms();
                                    parms.target        = Find.CurrentMap;
                                    parms.faction       = FactionColonies.getPlayerColonyFaction();
                                    parms.points        = 999;
                                    parms.raidArrivalModeForQuickMilitaryAid = true;
                                    parms.raidNeverFleeIndividual            = true;
                                    parms.raidForceOneIncap = true;
                                    parms.raidArrivalMode   = PawnsArrivalModeDefOf.CenterDrop;
                                    parms.raidStrategy      = RaidStrategyDefOf.ImmediateAttackFriendly;
                                    parms.raidArrivalModeForQuickMilitaryAid = true;
                                    PawnsArrivalModeWorker_EdgeWalkIn worker = new PawnsArrivalModeWorker_EdgeWalkIn();
                                    worker.TryResolveRaidSpawnCenter(parms);
                                    worker.Arrive(new List <Pawn> {
                                        pawn
                                    }, parms);

                                    Find.LetterStack.ReceiveLetter("FCMercenaryJoined".Translate(), "FCMercenaryJoinedText".Translate(pawn.NameFullColored), LetterDefOf.PositiveEvent, new LookTargets(pawn));
                                }
                                else
                                {
                                    Messages.Message("FCActionMercenaryOnCooldown".Translate(((faction.traitFeudalTickLastUsedMercenary + GenDate.TicksPerSeason) - Find.TickManager.TicksGame).ToStringTicksToDays()), MessageTypeDefOf.RejectInput);
                                }
                            }));
                        }


                        FloatMenu menu = new FloatMenu(list);
                        Find.WindowStack.Add(menu);
                    }
                }
            }
        }
Beispiel #24
0
        static bool Prefix(ref PawnGroupKindWorker_Trader __instance, PawnGroupMakerParms parms, PawnGroupMaker groupMaker, Pawn trader, List <Thing> wares, List <Pawn> outPawns)
        {
            if (parms.faction == FactionColonies.getPlayerColonyFaction())
            {
                List <PawnKindDef> list = new List <PawnKindDef>();
                foreach (ThingDef def in Find.World.GetComponent <FactionFC>().raceFilter.AllowedThingDefs)
                {
                    list.Add(def.race.AnyPawnKind);
                }

                if (!groupMaker.guards.Any <PawnGenOption>())
                {
                    return(false);
                }
                foreach (PawnGenOption pawnGenOption in PawnGroupMakerUtility.ChoosePawnGenOptionsByPoints(parms.points, groupMaker.guards, parms))
                {
                    PawnKindDef pawnkind = new PawnKindDef();
                    pawnkind = list.RandomElement();
                    pawnkind.techHediffsTags            = pawnGenOption.kind.techHediffsTags;
                    pawnkind.apparelTags                = pawnGenOption.kind.apparelTags;
                    pawnkind.isFighter                  = pawnGenOption.kind.isFighter;
                    pawnkind.combatPower                = pawnGenOption.kind.combatPower;
                    pawnkind.gearHealthRange            = pawnGenOption.kind.gearHealthRange;
                    pawnkind.weaponTags                 = pawnGenOption.kind.weaponTags;
                    pawnkind.apparelMoney               = pawnGenOption.kind.apparelMoney;
                    pawnkind.weaponMoney                = pawnGenOption.kind.weaponMoney;
                    pawnkind.apparelAllowHeadgearChance = pawnGenOption.kind.apparelAllowHeadgearChance;
                    pawnkind.techHediffsMoney           = pawnGenOption.kind.techHediffsMoney;
                    pawnkind.label = pawnGenOption.kind.label;

                    PawnGenerationRequest request = PawnGenerationRequest.MakeDefault();
                    request.KindDef = pawnkind;
                    Log.Message(request.KindDef.ToString());
                    request.Faction = parms.faction;
                    request.Tile    = parms.tile;
                    request.MustBeCapableOfViolence = true;
                    request.Inhabitant       = parms.inhabitants;
                    request.RedressValidator = ((Pawn x) => x.royalty == null || !x.royalty.AllTitlesForReading.Any <RoyalTitle>());
                    Pawn item = PawnGenerator.GeneratePawn(request);
                    outPawns.Add(item);
                }

                return(false);
            }
            else
            {
                return(true);
            }
        }
Beispiel #25
0
        // RimWorld.PawnGroupKindWorker_Normal
        public static void GeneratePawns_PostFix(PawnGroupMakerParms parms, PawnGroupMaker groupMaker, bool errorOnZeroResults, ref List <Pawn> __result)
        {
            //Anyone special?
            if (__result.Any() && __result.FindAll(x => x.TryGetComp <CompAbilityUser>() is CompAbilityUser cu && cu.CombatPoints() > 0) is List <Pawn> specialPawns)
            {
                //Log.Message("Special Pawns Detected");
                //Log.Message("------------------");

                //Points
                var previousPoints = parms.points;
                //Log.Message("Points: " +  previousPoints);

                //Log.Message("Average Characters");
                //Log.Message("------------------");

                //Anyone average?
                int avgPawns        = 0;
                var avgCombatPoints = new Dictionary <Pawn, float>();
                if (__result.FindAll(x => x.TryGetComp <CompAbilityUser>() == null) is List <Pawn> averagePawns)
                {
                    avgPawns = averagePawns.Count;
                    averagePawns.ForEach(x =>
                    {
                        avgCombatPoints.Add(x, x.kindDef.combatPower);
                        //Log.Message(x.LabelShort + " : " + x.kindDef.combatPower);
                    });
                }

                //Log.Message("------------------");
                //Log.Message("Special Characters");
                //Log.Message("------------------");

                //What's your powers?
                var specCombatPoints = new Dictionary <Pawn, float>();
                specialPawns.ForEach(x =>
                {
                    var combatValue = x.kindDef.combatPower;
                    foreach (var thingComp in x.AllComps.FindAll(y => y is CompAbilityUser))
                    {
                        //var compAbilityUser = (CompAbilityUser) thingComp;
                        var val      = Traverse.Create(thingComp).Method("CombatPoints").GetValue <float>();
                        combatValue += val; //compAbilityUser.CombatPoints();
                    }
                    specCombatPoints.Add(x, combatValue);
                    //Log.Message(x.LabelShort + " : " + combatValue);
                });


                //Special case -- single raider/character should not be special to avoid problems (e.g. Werewolf raid destroys everyone).
                if (avgPawns == 0 && specCombatPoints.Sum(x => x.Value) > 0 && specialPawns.Count == 1)
                {
                    //Log.Message("Special case called: Single character");
                    specialPawns.First().TryGetComp <CompAbilityUser>().DisableAbilityUser();
                    return;
                }

                //Should we rebalance?
                int tryLimit             = avgPawns + specialPawns.Count + 1;
                int initTryLimit         = tryLimit;
                var tempAvgCombatPoints  = new Dictionary <Pawn, float>(avgCombatPoints);
                var tempSpecCombatPoints = new Dictionary <Pawn, float>(specCombatPoints);
                var removedCharacters    = new List <Pawn>();
                while (previousPoints < tempAvgCombatPoints.Sum(x => x.Value) + tempSpecCombatPoints.Sum(x => x.Value))
                {
                    //Log.Message("------------------");
                    //Log.Message("Rebalance Attempt # " + (initTryLimit - tryLimit + 1));
                    //Log.Message("------------------");
                    //Log.Message("Scenario Points: " + previousPoints + ". Total Points: " + tempAvgCombatPoints.Sum(x => x.Value) + tempSpecCombatPoints.Sum(x => x.Value));

                    //In-case some stupid stuff occurs
                    --tryLimit;
                    if (tryLimit < 0)
                    {
                        break;
                    }

                    //If special characters outnumber the avg characters, try removing some of the special characters instead.
                    if (tempSpecCombatPoints.Count >= tempAvgCombatPoints.Count)
                    {
                        var toRemove = tempSpecCombatPoints.Keys.RandomElement();
                        //Log.Message("Removed: " + toRemove.LabelShort + " : " + tempSpecCombatPoints[toRemove]);
                        removedCharacters.Add(toRemove);
                        tempSpecCombatPoints.Remove(toRemove);
                    }
                    //If average characters outnumber special characters, then check if the combat value of avg is greater.
                    else if (tempSpecCombatPoints.Count < tempAvgCombatPoints.Count)
                    {
                        //Remove a random average character if the average characters have more combat points for a score
                        if (tempAvgCombatPoints.Sum(x => x.Value) > tempSpecCombatPoints.Sum(x => x.Value))
                        {
                            var toRemove = tempAvgCombatPoints.Keys.RandomElement();
                            //Log.Message("Removed: " + toRemove.LabelShort + " : " + tempSpecCombatPoints[toRemove]);
                            removedCharacters.Add(toRemove);
                            tempAvgCombatPoints.Remove(toRemove);
                        }
                        else
                        {
                            var toRemove = tempSpecCombatPoints.Keys.RandomElement();
                            //Log.Message("Removed: " + toRemove.LabelShort + " : " + tempSpecCombatPoints[toRemove]);
                            removedCharacters.Add(toRemove);
                            tempSpecCombatPoints.Remove(toRemove);
                        }
                    }
                }
                avgCombatPoints  = tempAvgCombatPoints;
                specCombatPoints = tempSpecCombatPoints;

//                Log.Message("------------");
//                Log.Message("Final Report");
//                Log.Message("------------");
//                Log.Message("Scenario Points: " + previousPoints + ". Total Points: " + tempAvgCombatPoints.Sum(x => x.Value) + tempSpecCombatPoints.Sum(x => x.Value));
//                Log.Message("------------");
//                Log.Message("Characters");
//                Log.Message("------------------");
                __result.ForEach(x =>
                {
                    var combatValue = x.kindDef.combatPower + x?.TryGetComp <CompAbilityUser>()?.CombatPoints() ?? 0f;
                    //Log.Message(x.LabelShort + " : " + combatValue);
                });
                foreach (var x in removedCharacters)
                {
                    if (x.TryGetComp <CompAbilityUser>() is CompAbilityUser cu && cu.CombatPoints() > 0)
                    {
                        cu.DisableAbilityUser();
                    }
Beispiel #26
0
        static bool Prefix(ref PawnGroupKindWorker_Normal __instance, PawnGroupMakerParms parms, PawnGroupMaker groupMaker, List <Pawn> outPawns, bool errorOnZeroResults = true)
        {
            if (parms.faction == FactionColonies.getPlayerColonyFaction())
            {
                List <PawnKindDef> list = new List <PawnKindDef>();
                foreach (ThingDef def in Find.World.GetComponent <FactionFC>().raceFilter.AllowedThingDefs)
                {
                    list.Add(def.race.AnyPawnKind);
                }



                if (!__instance.CanGenerateFrom(parms, groupMaker))
                {
                    if (errorOnZeroResults)
                    {
                        Log.Error(string.Concat(new object[]
                        {
                            "Cannot generate pawns for ",
                            parms.faction,
                            " with ",
                            parms.points,
                            ". Defaulting to a single random cheap group."
                        }), false);
                    }
                    return(false);
                }
                bool             allowFood         = parms.raidStrategy == null || parms.raidStrategy.pawnsCanBringFood || (parms.faction != null && !parms.faction.HostileTo(Faction.OfPlayer));
                Predicate <Pawn> validatorPostGear = (parms.raidStrategy != null) ? ((Pawn p) => parms.raidStrategy.Worker.CanUsePawn(p, outPawns)) : (Predicate <Pawn>)null;
                bool             flag = false;
                foreach (PawnGenOption pawnGenOption in PawnGroupMakerUtility.ChoosePawnGenOptionsByPoints(parms.points, groupMaker.options, parms))
                {
                    PawnKindDef pawnkind = new PawnKindDef();
                    pawnkind = list.RandomElement();
                    pawnkind.techHediffsTags            = pawnGenOption.kind.techHediffsTags;
                    pawnkind.apparelTags                = pawnGenOption.kind.apparelTags;
                    pawnkind.isFighter                  = pawnGenOption.kind.isFighter;
                    pawnkind.combatPower                = pawnGenOption.kind.combatPower;
                    pawnkind.gearHealthRange            = pawnGenOption.kind.gearHealthRange;
                    pawnkind.weaponTags                 = pawnGenOption.kind.weaponTags;
                    pawnkind.apparelMoney               = pawnGenOption.kind.apparelMoney;
                    pawnkind.weaponMoney                = pawnGenOption.kind.weaponMoney;
                    pawnkind.apparelAllowHeadgearChance = pawnGenOption.kind.apparelAllowHeadgearChance;
                    pawnkind.techHediffsMoney           = pawnGenOption.kind.techHediffsMoney;
                    pawnkind.label = pawnGenOption.kind.label;


                    Pawn pawn = PawnGenerator.GeneratePawn(new PawnGenerationRequest(pawnkind, parms.faction, PawnGenerationContext.NonPlayer, parms.tile, false, false, false, false, true, true, 1f, false, true, allowFood, true, parms.inhabitants, false, false, false, 0f, null, 1f, null, validatorPostGear, null, null, null, null, null, null, null, null, null, null));
                    if (parms.forceOneIncap && !flag)
                    {
                        pawn.health.forceIncap           = true;
                        pawn.mindState.canFleeIndividual = false;
                        flag = true;
                    }
                    outPawns.Add(pawn);
                }
                return(false);
            }
            else
            {
                return(true);
            }
        }