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); }
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)); }
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."); } } }
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."); } } }
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)); } } }