示例#1
0
        private static Blueprint PlaceEntranceBlueprint()
        {
            if (!availableCrates.Any(c => c.def == _DefOf.Carn_Crate_Stall))
            {
                return(null);
            }

            ThingDef bannerDef = _DefOf.Carn_SignEntry;
            Rot4     rot       = default(Rot4);

            IntVec3 bannerSpot = FindRadialPlacementFor(bannerDef, rot, info.bannerCell, 16);

            if (bannerSpot.IsValid)
            {
                info.bannerCell = bannerSpot;

                if (Prefs.DevMode)
                {
                    Log.Message("[Carnivale] bannerCell final pass: "******"Couldn't find an optimum place for " + bannerDef + ". Trying random place in carnival area.");
            bannerSpot = FindRandomPlacementFor(bannerDef, rot);

            if (bannerSpot.IsValid)
            {
                info.bannerCell = bannerSpot;

                if (Prefs.DevMode)
                {
                    Log.Message("[Carnivale] bannerCell final pass: "******"Couldn't find any place for " + bannerDef + ". Not retrying.");
            return(null);
        }
示例#2
0
        private static Blueprint PlaceTrashBlueprint()
        {
            var     signDef = _DefOf.Carn_SignTrash;
            var     noGo    = CellRect.CenteredOn(info.bannerCell, 10);
            IntVec3 trashPos;

            if (!CellRect.CenteredOn(info.bannerCell, 15).Cells
                .Where(c => !noGo.Contains(c))
                .TryRandomElement(out trashPos))
            {
                if (Prefs.DevMode)
                {
                    Log.Message("[Carnivale] New trash position calculation failed. Using old method.");
                }

                trashPos = info.carnivalArea.ContractedBy(5).FurthestCellFrom(cachedPos.Average(), true, delegate(IntVec3 c)
                {
                    if (noGo.Contains(c))
                    {
                        return(false);
                    }

                    return(true);
                });
            }

            if (!CanPlaceBlueprintAt(trashPos, signDef))
            {
                trashPos = FindRadialPlacementFor(signDef, default(Rot4), trashPos, 10);
            }

            if (!trashPos.IsValid)
            {
                Log.Error("[Carnivale] Could not find any place for a trash spot. Trash will not be hauled.");
                info.TrashCentre = IntVec3.Invalid;
                return(null);
            }

            info.TrashCentre = trashPos;

            RemoveFirstCrateOf(ThingDefOf.WoodLog);
            CarnUtils.ClearThingsFor(info.map, trashPos, new IntVec2(4, 4), default(Rot4));
            return(PlaceBlueprint(signDef, trashPos, default(Rot4), ThingDefOf.WoodLog));
        }
示例#3
0
        private static IEnumerable <Blueprint> PlaceGameBlueprints()
        {
            var gameMasters = stallUsers.Where(p => p.TraderKind == null).ToList();
            var gameCrates  = availableCrates.ListFullCopy().Where(c => c.def.entityDefToBuild != null);

            var points = new IntVec3[]
            {
                info.setupCentre,
                info.bannerCell
            };

            var gameSpot = CellRect.CenteredOn(points.Average(), 7).FurthestCellFrom(info.carnivalArea.EdgeCells.RandomElement());

            ThingDef gameDef;
            int      i = 0;

            foreach (var crate in gameCrates)
            {
                gameDef = (ThingDef)crate.def.entityDefToBuild;

                gameSpot = FindRadialPlacementFor(gameDef, default(Rot4), gameSpot, 20);

                if (gameSpot.IsValid)
                {
                    RemoveFirstCrateOf(crate.def);
                    CarnUtils.ClearThingsFor(info.map, gameSpot, gameDef.size, default(Rot4), 2);

                    if (i < gameMasters.Count)
                    {
                        IntVec3 gameMasterSpot = gameSpot + gameDef.interactionCellOffset + new IntVec3(-1, 0, 1);
                        info.rememberedPositions.Add(gameMasters[i++], gameMasterSpot);
                    }

                    yield return(PlaceBlueprint(gameDef, gameSpot));
                }
                else
                {
                    Log.Error("Found no place for " + gameDef + ". It will not be built.");
                }
            }
        }
示例#4
0
        protected List <Pawn> SpawnPawns(IncidentParms parms, int spawnPointSpread)
        {
            Map map = (Map)parms.target;

            if (parms.spawnRotation != Rot4.East)
            {
                if (Prefs.DevMode)
                {
                    Log.Message("[Carnivale] Spawn centre for CarnivalArrives was not precomputed. Resolving now.");
                }

                IntVec3 tempSpot = parms.spawnCenter;

                if (CarnCellFinder.BestCarnivalSpawnSpot(map, out tempSpot))
                {
                    parms.spawnCenter = tempSpot;
                }
                else if (Prefs.DevMode)
                {
                    Log.Warning("[Carnivale] Failed to resolve spawn center for CarnivalArrives. Defaulting.");
                }

                int feePerColonist = CarnUtils.CalculateFeePerColonist(parms.points);
                CarnUtils.Info.feePerColonist = -feePerColonist;
            }

            PawnGroupMakerParms defaultMakerParms = IncidentParmsUtility.GetDefaultPawnGroupMakerParms(parms);

            List <Pawn> list = PawnGroupMakerUtility.GeneratePawns(this.PawnGroupKindDef, defaultMakerParms, false).ToList();

            foreach (Pawn p in list)
            {
                IntVec3 spawnPoint = CellFinder.RandomClosewalkCellNear(parms.spawnCenter, map, spawnPointSpread, null);
                GenSpawn.Spawn(p, spawnPoint, map);
            }

            parms.faction.leader.skills.GetSkill(SkillDefOf.Shooting).levelInt = 9;

            return(list);
        }
示例#5
0
        public override void MapLoaded(Map map)
        {
            base.MapLoaded(map);

            CarnUtils.Cleanup();
        }
示例#6
0
        public override bool TryExecute(IncidentParms parms)
        {
            Map     map = (Map)parms.target;
            IntVec3 spawnSpot;
            int     durationDays = Mathf.RoundToInt(this.def.durationDays.RandomInRange);

            if (Prefs.DevMode)
            {
                Log.Message("[Carnivale] Calculating spawn centre:");
            }

            if (!CarnCellFinder.BestCarnivalSpawnSpot(map, out spawnSpot))
            {
                if (Prefs.DevMode)
                {
                    Log.Warning("[Carnivale] Tried to execute incident CarnivalApproaches, failed to find reachable spawn spot.");
                }
                return(false);
            }

            if (!FindCarnivalFaction(out parms.faction))
            {
                if (Prefs.DevMode)
                {
                    Log.Warning("[Carnivale] Tried to execute incident CarnivalApproaches, failed to find valid faction.");
                }
                return(false);
            }

            // Calculate fe
            int feePerColonist = CarnUtils.CalculateFeePerColonist(parms.points);

            // Main dialog node
            string  title       = "CarnivalApproachesTitle".Translate(parms.faction.Name);
            DiaNode initialNode = new DiaNode("CarnivalApproachesInitial".Translate(new object[]
            {
                parms.faction.Name,
                durationDays,
                feePerColonist + " " + ThingDefOf.Silver.label,
                map.info.parent.Label == "Colony" ? "your colony" : map.info.parent.Label
            }));

            // Accept button
            DiaOption acceptOption = new DiaOption("CarnivalApproachesAccept".Translate());

            acceptOption.action = delegate
            {
                // Do accept action
                parms.faction.AffectGoodwillWith(Faction.OfPlayer, acceptanceBonus);

                IncidentParms arrivalParms = StorytellerUtility.DefaultParmsNow(Find.Storyteller.def, IncidentCategory.AllyArrival, map);
                //arrivalParms.forced = true; // forcing not necessary
                arrivalParms.faction     = parms.faction;
                arrivalParms.spawnCenter = spawnSpot;
                arrivalParms.points      = parms.points; // Do this?

                // This is so it can be determined that the spawnpoint was precomputed.
                Rot4 sneakyValueForSpawnpointResolved = Rot4.East;
                arrivalParms.spawnRotation = sneakyValueForSpawnpointResolved;

                // This is super cheaty, but there is no other field to pass this to.
                arrivalParms.raidPodOpenDelay = durationDays;
                // End cheaty.

                // Assign fee per colonist to CarnivalInfo
                CarnUtils.Info.feePerColonist = -feePerColonist;

                QueuedIncident qi = new QueuedIncident(new FiringIncident(_DefOf.CarnivalArrives, null, arrivalParms), Find.TickManager.TicksGame + GenDate.TicksPerDay);
                Find.Storyteller.incidentQueue.Add(qi);
            };
            initialNode.options.Add(acceptOption);

            // Accept thank you message
            DiaNode acceptedMessage = new DiaNode("CarnivalApproachesAcceptMessage".Translate(new object[]
            {
                parms.faction.leader.Name.ToStringFull
            }));
            DiaOption ok = new DiaOption("OK".Translate());

            ok.resolveTree = true;
            acceptedMessage.options.Add(ok);
            acceptOption.link = acceptedMessage;

            // Reject button
            DiaOption rejectOption = new DiaOption("CarnivalApproachesReject".Translate());

            rejectOption.action = delegate
            {
                // Do reject action
                parms.faction.AffectGoodwillWith(Faction.OfPlayer, rejectionPenalty);
            };
            initialNode.options.Add(rejectOption);

            // Reject f**k you message (TODO: randomise response)
            DiaNode rejectedMessage = new DiaNode("CarnivalApproachesRejectMessage".Translate(new object[]
            {
                parms.faction.leader.Name.ToStringShort
            }));
            DiaOption hangup = new DiaOption("HangUp".Translate());

            hangup.resolveTree = true;
            rejectedMessage.options.Add(hangup);
            rejectOption.link = rejectedMessage;

            // Draw dialog
            Find.WindowStack.Add(new Dialog_NodeTree(initialNode, true, true, title));

            return(true);
        }
示例#7
0
        public override bool TryExecute(IncidentParms parms)
        {
            Map map = (Map)parms.target;
            // Cheaty:
            int durationDays = parms.raidPodOpenDelay == 140 ? 3 : parms.raidPodOpenDelay;

            // End cheaty.

            // Resolve parms (currently counting on parent class to handle this)
            if (!base.TryResolveParms(parms))
            {
                if (Prefs.DevMode)
                {
                    Log.Warning("[Carnivale] Could not execute CarnivalArrives: the spawn point calculated yesterday is probably no longer valid.");
                }
                return(false);
            }

            // Spawn pawns. Counting on you, IncidentWorker_NeutralGroup.
            List <Pawn> pawns = this.SpawnPawns(parms, 17);

            if (pawns.Count < 3)
            {
                if (Prefs.DevMode)
                {
                    Log.Warning("[Carnivale] Could not execute CarnivalArrives: could not generate enough valid pawns.");
                }
                return(false);
            }

            List <Pawn> vendors = new List <Pawn>();

            foreach (Pawn p in pawns)
            {
                if (p.TraderKind != null)
                {
                    // Get list of vendors
                    vendors.Add(p);
                }
                if (p.needs != null && p.needs.food != null)
                {
                    // Also feed the carnies
                    p.needs.food.CurLevel = p.needs.food.MaxLevel;
                }
            }

            string label = "LetterLabelCarnivalArrival".Translate();

            string text = "LetterCarnivalArrival".Translate(parms.faction.Name, durationDays);

            if (vendors.Count > 0)
            {
                text += "CarnivalArrivalVendorsList".Translate();
                foreach (Pawn vendor in vendors)
                {
                    text += "\n  " + vendor.NameStringShort + ", " + vendor.TraderKind.label.CapitalizeFirst();
                }
            }

            PawnRelationUtility.Notify_PawnsSeenByPlayer(pawns, ref label, ref text, "LetterRelatedPawnsNeutralGroup".Translate(), true);
            Find.LetterStack.ReceiveLetter(label, text, LetterDefOf.Good, parms.faction.leader, null);

            //LordJob_EntertainColony lordJob = new LordJob_EntertainColony(durationDays);
            //Lord lord = LordMaker.MakeNewLord(parms.faction, lordJob, map, pawns);

            //CarnivalUtils.Info.ReInitWith(lord, parms.spawnCenter);

            CarnUtils.MakeNewCarnivalLord(parms.faction, map, parms.spawnCenter, durationDays, pawns);

            return(true);
        }
示例#8
0
        private static IEnumerable <Blueprint> PlaceTentBlueprints()
        {
            // main chapiteau
            ThingDef tentDef;
            Rot4     rot = info.setupCentre.RotationFacing(info.bannerCell).Opposite;
            IntVec3  tentSpot;

            if (availableCrates.Any(c => c.def == _DefOf.Carn_Crate_TentHuge))
            {
                tentDef  = _DefOf.Carn_TentChap;
                tentSpot = FindRadialPlacementFor(tentDef, rot, info.setupCentre, 11);
                if (tentSpot.IsValid)
                {
                    RemoveFirstCrateOf(_DefOf.Carn_Crate_TentHuge);
                    CarnUtils.ClearThingsFor(info.map, tentSpot, tentDef.size, rot, 2);
                    yield return(PlaceBlueprint(tentDef, tentSpot, rot));
                }
                else
                {
                    Log.Error("Could not find placement for " + tentDef + ", which is a major attraction. Tell Xnope to get it together.");
                }
            }



            // lodging tents
            tentDef  = _DefOf.Carn_TentLodge;
            rot      = Rot4.Random;
            tentSpot = FindRadialPlacementFor(tentDef, rot, info.carnivalArea.ContractedBy(9).FurthestCellFrom(CellsUtil.AverageColonistPosition(info.map)), 7);

            IntVec3 lineDirection = rot.ToIntVec3(1); // shifted clockwise by 1

            int  numFailures  = 0;
            bool firstNewPass = true;

            while (numFailures < 30 && availableCrates.Any(t => t.def == _DefOf.Carn_Crate_TentLodge))
            {
                // Following works as intended iff size.x == size.y

                if (!firstNewPass)
                {
                    // try adding tent next in a an adjacent line
                    tentSpot += lineDirection * ((tentDef.size.x + 1));
                }

                if (CanPlaceBlueprintAt(tentSpot, tentDef, rot))
                {
                    // bingo
                    firstNewPass = false;
                    RemoveFirstCrateOf(_DefOf.Carn_Crate_TentLodge);
                    CarnUtils.ClearThingsFor(info.map, tentSpot, tentDef.size, rot, 1);
                    yield return(PlaceBlueprint(tentDef, tentSpot, rot));
                }
                else if (numFailures % 3 != 0)
                {
                    // try different line directions
                    rot.AsByte++;
                    lineDirection = rot.ToIntVec3(1);
                    numFailures++;
                }
                else
                {
                    // Find new placement if next spot and any of its rotations don't work
                    tentSpot = FindRadialPlacementFor(tentDef, rot, tentSpot, (int)info.baseRadius / 2);

                    if (!tentSpot.IsValid)
                    {
                        // suboptimal random placement
                        tentSpot = FindRandomPlacementFor(tentDef, rot, false, 5);
                    }

                    firstNewPass = true;
                }
            }

            if (numFailures == 30 && availableCrates.Any(t => t.def == _DefOf.Carn_Crate_TentLodge))
            {
                Log.Error("Tried too many times to place tents. Some may not be built.");
            }

            // manager tent
            if (!availableCrates.Any(c => c.def == _DefOf.Carn_Crate_TentMan))
            {
                yield break;
            }

            rot     = Rot4.Random;
            tentDef = _DefOf.Carn_TentLodgeMan;

            // Try to place near other tents
            tentSpot = FindRadialCardinalPlacementFor(tentDef, rot, tentSpot, 10);

            if (tentSpot.IsValid)
            {
                RemoveFirstCrateOf(_DefOf.Carn_Crate_TentMan);
                CarnUtils.ClearThingsFor(info.map, tentSpot, tentDef.size, rot, 1);
                yield return(PlaceBlueprint(tentDef, tentSpot, rot));
            }
            else
            {
                // suboptimal placement
                tentSpot = FindRadialPlacementFor(tentDef, rot, info.setupCentre, (int)info.baseRadius / 2);
                if (tentSpot.IsValid)
                {
                    RemoveFirstCrateOf(_DefOf.Carn_Crate_TentMan);
                    CarnUtils.ClearThingsFor(info.map, tentSpot, tentDef.size, rot, 1);
                    yield return(PlaceBlueprint(tentDef, tentSpot, rot));
                }
                else
                {
                    Log.Error("Found no valid placement for manager tent. It will not be placed.");
                }
            }
        }
示例#9
0
        private static IEnumerable <Blueprint> PlaceStallBlueprints()
        {
            ThingDef stallDef  = _DefOf.Carn_StallFood;
            IntVec3  stallSpot = IntVec3.Invalid;
            Rot4     rot       = default(Rot4);

            foreach (Pawn stallUser in stallUsers.Where(p => p.TraderKind != null))
            {
                // Handle different kinds of vendor stalls

                if (stallUser.TraderKind == _DefOf.Carn_Trader_Food)
                {
                    stallDef = _DefOf.Carn_StallFood;
                }
                else if (stallUser.TraderKind == _DefOf.Carn_Trader_Surplus)
                {
                    stallDef = _DefOf.Carn_StallSurplus;
                }
                else if (stallUser.TraderKind == _DefOf.Carn_Trader_Curios)
                {
                    stallDef = _DefOf.Carn_StallCurios;
                }
                else
                {
                    Log.Error("Trader " + stallUser.NameStringShort + " is not a carnival vendor and will get no stall.");
                    continue;
                }



                if (stallSpot.IsValid)
                {
                    if (Rand.Chance(0.8f))
                    {
                        // Next spot should be close to last spot
                        stallSpot = FindRadialCardinalPlacementFor(stallDef, rot, stallSpot, 10);
                    }
                    else
                    {
                        // Next spot should be random
                        IntVec3[] points = new IntVec3[]
                        {
                            stallSpot,
                            stallSpot,
                            info.carnivalArea.EdgeCells.RandomElement()
                        };

                        stallSpot = FindRadialPlacementFor(stallDef, rot, points.Average(), 10);
                    }
                }
                else
                {
                    IntVec3[] points = new IntVec3[]
                    {
                        info.setupCentre,
                        info.bannerCell
                    };

                    stallSpot = FindRadialPlacementFor(stallDef, rot, points.Average(), 10);
                }


                // Finally, spawn the f*cker
                if (stallSpot.IsValid)
                {
                    RemoveFirstCrateOf(_DefOf.Carn_Crate_Stall);
                    CarnUtils.ClearThingsFor(info.map, stallSpot, stallDef.size, rot, 2);
                    // Add spot to stall user's spot
                    info.rememberedPositions.Add(stallUser, stallSpot);
                    yield return(PlaceBlueprint(stallDef, stallSpot, rot));
                }
            }
        }
示例#10
0
        public override IEnumerable <FloatMenuOption> CompFloatMenuOptions(Pawn pawn)
        {
            if (Props.useJob == null)
            {
                // no useJob specified
                yield break;
            }

            if (parent.Faction != pawn.Faction)
            {
                if (!Info.Active)
                {
                    // carnival is not in town for whatever reason
                    yield break;
                }
                else if (!Info.entertainingNow)
                {
                    // Carnival is closed
                    yield return(new FloatMenuOption(this.FloatMenuOptionLabel + " (Carnival closed)", null));
                }
                else if (!pawn.CanReserve(this.parent))
                {
                    // Already reserved
                    yield return(new FloatMenuOption(this.FloatMenuOptionLabel + " (" + "Reserved".Translate() + ")", null));
                }
                else if (Props.useJob == _DefOf.Job_PayEntryFee)
                {
                    // Pay entry fee
                    yield return(new FloatMenuOption(this.FloatMenuOptionLabel + " (" + Info.feePerColonist + ")", delegate
                    {
                        var silverCount = new ThingCountClass(ThingDefOf.Silver, Info.feePerColonist);
                        var silverStack = CarnUtils.FindClosestThings(pawn, silverCount);

                        if (silverStack != null && pawn.CanReserveAndReach(silverStack, PathEndMode.Touch, pawn.NormalMaxDanger()))
                        {
                            var job = new Job(Props.useJob, silverStack)
                            {
                                expiryInterval = GenDate.TicksPerHour * 10
                            };
                            pawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
                        }
                    }));
                }
                else if (!Info.allowedColonists.Contains(pawn))
                {
                    // Pawn hasn't payed entry fee
                    yield return(new FloatMenuOption(this.FloatMenuOptionLabel + " (Must pay fee at entrance)", null));
                }
                else if (Props.type.Is(CarnBuildingType.Stall | CarnBuildingType.Attraction))
                {
                    // Do use job (mostly for games)
                    yield return(new FloatMenuOption(this.FloatMenuOptionLabel, delegate
                    {
                        if (pawn.CanReserveAndReach(this.parent, PathEndMode.InteractionCell, Danger.None))
                        {
                            this.TryStartUseJob(pawn);
                        }
                    }));
                }
            }
            else
            {
                if (!pawn.CanReserve(this.parent))
                {
                    // Already reserved
                    yield return(new FloatMenuOption(this.FloatMenuOptionLabel + " (" + "Reserved".Translate() + ")", null));
                }
                else if (Props.type.Is(CarnBuildingType.Stall | CarnBuildingType.Attraction))
                {
                    // Do use job (mostly for games)
                    yield return(new FloatMenuOption(this.FloatMenuOptionLabel, delegate
                    {
                        if (pawn.CanReserveAndReach(this.parent, PathEndMode.InteractionCell, Danger.None))
                        {
                            this.TryStartUseJob(pawn);
                        }
                    }));
                }
            }
        }
示例#11
0
        public override void SpawnSetup(Map map, bool respawningAfterLoad)
        {
            // Forbid things so colonists can access them after they are hauled to trash
            if (this.factionInt != Faction.OfPlayer)
            {
                var occ  = this.OccupiedRect().ExpandedBy(2);
                var tele = occ.ExpandedBy(1);

                foreach (var cell in occ)
                {
                    foreach (var thing in cell.GetThingList(map))
                    {
                        if (thing.def.EverHaulable)
                        {
                            thing.SetForbidden(true, false);
                        }
                        if (thing is Pawn && (thing.Faction == null || thing.Faction != this.Faction))
                        {
                            thing.Position = tele.Cells.Where(c => !c.GetThingList(map).Any(t => t is Building)).RandomElement();
                        }
                    }
                }
            }

            // Build interior
            if (Props.interiorThings.Any() && !childBuildings.Any(b => Props.interiorThings.Any(t => t.thingDef == b.def)))
            {
                this.oldPosition = Position;

                foreach (ThingPlacement tp in Props.interiorThings)
                {
                    foreach (IntVec3 offset in tp.placementOffsets)
                    {
                        IntVec3  cell  = Position + offset.RotatedBy(Rotation);
                        ThingDef stuff = tp.thingDef.MadeFromStuff ? GenStuff.DefaultStuffFor(tp.thingDef) : null;

                        Building building = ThingMaker.MakeThing(tp.thingDef, stuff) as Building;
                        building.SetFaction(this.Faction);
                        building.Position = cell;
                        building.Rotation = this.Rotation.Opposite;

                        // Give manager a specific bed:
                        if (this.Type.Is(CarnBuildingType.Bedroom | CarnBuildingType.ManagerOnly))
                        {
                            if (building is Building_Bed && this.Faction != Faction.OfPlayer)
                            {
                                this.Faction.leader.ownership.ClaimBedIfNonMedical((Building_Bed)building);
                            }
                        }

                        childBuildings.Add(building);

                        //Utilities.SpawnThingNoWipe(building, cell, map, Rotation.Opposite, respawningAfterLoad);
                    }
                }
            }

            foreach (var child in childBuildings)
            {
                // spawn here
                if (!child.Spawned)
                {
                    // offset is necessary for reinstallation
                    IntVec3 offset = child.Position - this.oldPosition;
                    child.Position = this.Position + offset;
                    CarnUtils.SpawnThingNoWipe(child, map, respawningAfterLoad);
                }
            }

            base.SpawnSetup(map, respawningAfterLoad);

            if (childBuildings.Any())
            {
                // Necessary for reinstalling properly
                this.oldPosition = this.Position;
            }
        }
示例#12
0
        // OVERRIDE METHODS //


        public override void Init()
        {
            base.Init();

            LordToilData_SetupCarnival data = (LordToilData_SetupCarnival)this.data;


            // Give em a wood for trash sign
            var log = ThingMaker.MakeThing(ThingDefOf.WoodLog);

            log.stackCount = 1;
            GenPlace.TryPlaceThing(log, Info.setupCentre, Map, ThingPlaceMode.Near);


            // Give chapiteau
            if (data.TryHaveWorkerCarry(_DefOf.Carn_Crate_TentHuge, 1, CarnUtils.RandomFabricByCheapness()) != 1)
            {
                Log.Error("[Carnivale] Could not give " + _DefOf.Carn_Crate_TentHuge + " to carnies of faction " + lord.faction + ". It will not be built.");
            }


            // Give lodging tents (currently 8 carnies per lodging tent)

            int numCarnies = this.lord.ownedPawns.Count - Info.pawnsWithRole[CarnivalRole.Carrier].Count;

            int numBedTents = numCarnies > 9 ? Mathf.CeilToInt(numCarnies / 8f) : 1;

            if (data.TryHaveWorkerCarry(_DefOf.Carn_Crate_TentLodge, numBedTents, CarnUtils.RandomFabricByCheapness()) != numBedTents)
            {
                Log.Error("[Carnivale] Could not give enough " + _DefOf.Carn_Crate_TentLodge + " to carnies of faction " + lord.faction + ". Some will not be built.");
            }

            if (Info.pawnsWithRole[CarnivalRole.Manager].Any())
            {
                if (data.TryHaveWorkerCarry(_DefOf.Carn_Crate_TentMan, 1, CarnUtils.RandomFabricByExpensiveness()) != 1)
                {
                    Log.Error("[Carnivale] Could not give " + _DefOf.Carn_Crate_TentMan + " to carnies of faction " + lord.faction + ". It will not be built.");
                }
            }


            // Give vendor stalls + entry sign
            int numStallCrates = Info.pawnsWithRole[CarnivalRole.Vendor].Count + _DefOf.Carn_SignEntry.costList.First().count;

            data.TryHaveWorkerCarry(_DefOf.Carn_Crate_Stall, numStallCrates, ThingDefOf.WoodLog);


            // Give game stalls
            data.TryHaveWorkerCarry(_DefOf.Carn_Crate_GameHighStriker, 1, ThingDefOf.WoodLog);


            // Place blueprints
            foreach (Blueprint bp in AIBlueprintsUtility.PlaceCarnivalBlueprints(Info))
            {
                data.blueprints.Add(bp);
            }

            // Find spots for carriers to chill + a guard spot
            var guardSpot = GetCarrierSpots().Average();

            // Assign guard spot at carriers
            Pawn guard = Info.GetBestGuard();

            if (guard != null)
            {
                //Info.rememberedPositions.Add(guard, guardSpot);
                Info.guardPositions.Add(guardSpot);

                // if can feed animals, give em kibble
                if (!guard.story.WorkTypeIsDisabled(WorkTypeDefOf.Handling))
                {
                    Thing kib = ThingMaker.MakeThing(ThingDefOf.Kibble);
                    kib.stackCount = 75;
                    guard.inventory.TryAddItemNotForSale(kib);
                }
            }
        }
示例#13
0
 public override void Cleanup()
 {
     base.Cleanup();
     Info.Cleanup();
     CarnUtils.Cleanup();
 }