protected void PrintSetup() { if (typeof(T) != typeof(GridType)) { return; } MultiMap <GridType> tmpArr = new MultiMap <GridType>(); foreach (Value2D <T> val in container) { tmpArr[val] = (GridType)(object)container[val]; } foreach (Value2D <JumpSetup> setup in jumps) { tmpArr[setup] = GridType.INTERNAL_RESERVED_BLOCKED; } foreach (Value2D <GridType> val in Enumerate().Cast <Point>()) { tmpArr[val] = GridType.INTERNAL_RESERVED_CUR; } foreach (Value2D <GridType> val in Path.PathPrint(Enumerate().Cast <Point>())) { tmpArr[val] = val.val; } tmpArr.ToLog(Logs.LevelGen); }
public override bool Place(Container2D <GenSpace> grid, LayoutObject obj, Theme theme, System.Random rand, out Boxing placed) { List <Bounding> options = obj.FindRectangles(GridWidth, GridLength, true, UnitTest); options = new List <Bounding>(options.Filter((bounds) => { Counter counter = new Counter(); grid.DrawRect(new Bounding(bounds, 1), FrontTest.IfThen(Draw.Count <GenSpace>(counter))); return(counter > 0); })); if (options.Count == 0) { placed = null; return(false); } #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen) && BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps)) { BigBoss.Debug.w(Logs.LevelGen, "Options:"); if (GridWidth == 1 && GridLength == 1) { MultiMap <GenSpace> tmp = new MultiMap <GenSpace>(); tmp.PutAll(obj); foreach (Bounding bounds in options) { tmp.DrawRect(bounds, Draw.SetTo(GridType.INTERNAL_RESERVED_CUR, theme)); } tmp.ToLog(Logs.LevelGen); } else { foreach (Bounding bounds in options) { MultiMap <GenSpace> tmp = new MultiMap <GenSpace>(); tmp.PutAll(obj); tmp.DrawRect(bounds, Draw.SetTo(GridType.INTERNAL_RESERVED_CUR, theme)); tmp.ToLog(Logs.LevelGen); } } } #endregion // Place startpoints placed = null; return(false); //placed = options.Random(rand); placed.Expand(1); GridLocation side = GridLocation.BOTTOMRIGHT; foreach (GridLocation loc in GridLocationExt.Dirs().Randomize(rand)) { if (obj.DrawEdge(placed, loc, UnitTest, false)) { side = loc; break; } } obj.DrawEdge(placed, side, Draw.SetTo(GridType.StairPlace, theme), false); return(true); }
protected override bool ModifyInternal(RoomSpec spec) { UndeadTombTheme undeadTheme = spec.Theme as UndeadTombTheme; if (undeadTheme == null) { throw new ArgumentException("Theme needs to be undead themed."); } var tombCollection = undeadTheme.Tombs.SmartElement; ThemeElement tombProto = tombCollection.Proto; List <List <Bounding> > options = spec.Grids.FindRectanglesMaximized(tombProto.GridWidth + 2, tombProto.GridLength + 2, true, new StrokedAction <GenSpace>() { UnitAction = Draw.IsType <GenSpace>(GridType.Floor), StrokeAction = Draw.Walkable() }, spec.Grids.Bounding); #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen) && BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps)) { BigBoss.Debug.printHeader(Logs.LevelGen, "Printing tomb layout options"); for (int i = 0; i < options.Count; i++) { MultiMap <GenSpace> tmp = new MultiMap <GenSpace>(spec.Grids); foreach (Bounding bound in options[i]) { tmp.DrawRect(bound.XMin, bound.XMax, bound.YMin, bound.YMax, new StrokedAction <GenSpace>() { UnitAction = Draw.SetTo(GridType.Wall, spec.Theme), StrokeAction = Draw.True <GenSpace>() }); } tmp.ToLog(Logs.LevelGen, "Option " + i); } BigBoss.Debug.printFooter(Logs.LevelGen, "Printing tomb layout options"); } #endregion while (options.Count > 0) { List <Bounding> set = options.RandomTake(spec.Random); if (set.Count > MIN_TOMBS) { foreach (Bounding tombBound in set) { GenDeploy tomb = new GenDeploy(tombCollection.Get(spec.Random)); spec.Grids.DrawRect(tombBound.XMin, tombBound.XMax, tombBound.YMin, tombBound.YMax, new StrokedAction <GenSpace>() { UnitAction = Draw.MergeIn(tomb, spec.Theme), StrokeAction = Draw.True <GenSpace>() }); } return(true); } } return(false); }
protected override bool ModifyInternal(RoomSpec spec, double scale) { spec.RoomModifiers.RemoveMod(this); BaseRoomMod baseMod = spec.RoomModifiers.BaseMods.Get(spec.Random); #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.w(Logs.LevelGen, "Picked base mod " + baseMod); } #endregion scale *= 2d; baseMod.Modify(spec, scale); int numTombs = spec.Random.Next(2, 5) * 2; List <Bounding> largestRects = spec.Grids.FindLargestRectangles(false, new StrokedAction <GenSpace>() { UnitAction = Draw.IsType <GenSpace>(GridType.Floor) }, spec.Grids.Bounding); if (largestRects.Count == 0) { return(false); } #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen) && BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps)) { BigBoss.Debug.w(Logs.LevelGen, "Largest Rect Options"); foreach (Bounding bounds in largestRects) { MultiMap <GenSpace> tmp = new MultiMap <GenSpace>(spec.Grids); tmp.DrawRect(bounds, new StrokedAction <GenSpace>() { UnitAction = Draw.SetTo(GridType.INTERNAL_RESERVED_BLOCKED, spec.Theme) }); tmp.ToLog(Logs.LevelGen); } } #endregion Bounding bound = largestRects.Random(spec.Random); // Place tombs int buffer = spec.Random.NextBool() ? 1 : 2; int pillarSize = 3; // Place pillars //spec.Grids.DrawRect(bound.XMin + buffer, bound.XMin + pillarSize + buffer - 1, bound.YMin + buffer, bound.YMin + pillarSize + buffer - 1, Draw.SetTo(GridType.Pillar, spec.Theme)); //spec.Grids.DrawRect(bound.XMax - 3, bound.XMin + 3, bound.YMin, bound.YMin + 3, Draw.SetTo(GridType.Pillar, spec.Theme)); //spec.Grids.DrawRect(bound.XMin, bound.XMin + 3, bound.YMin, bound.YMin + 3, Draw.SetTo(GridType.Pillar, spec.Theme)); //spec.Grids.DrawRect(bound.XMin, bound.XMin + 3, bound.YMin, bound.YMin + 3, Draw.SetTo(GridType.Pillar, spec.Theme)); // Remove more tomb mods spec.RoomModifiers.RemoveMod(new MassTombRoom(), true); return(false); }
public override bool Place(Container2D <GenSpace> grid, LayoutObject obj, Theme theme, Random rand, out Boxing placed) { int max = Math.Max(GridWidth, GridLength); List <Boxing> options = new List <Boxing>( grid.FindBoxes( GridWidth, GridLength, GridLocation.TOP, new BoxedAction <GenSpace>( frontTest.And(Draw.ContainedIn(obj)), unitTest), true, true, obj.Bounding.Expand(max)) .Filter((box) => { Counter counter = new Counter(); bool ret = grid.DrawEdge(box, box.Front, Draw.HasAround(false, Draw.And(Draw.IsType <GenSpace>(GridType.Floor), Draw.Count <GenSpace>(counter)). Or(Draw.Walkable()))); return(ret && counter > 0); })); if (options.Count == 0) { placed = null; return(false); } #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen) && BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps)) { BigBoss.Debug.w(Logs.LevelGen, "Options:"); foreach (Boxing boxing in options) { MultiMap <GenSpace> tmp = new MultiMap <GenSpace>(); tmp.PutAll(obj); tmp.DrawRect(boxing, Draw.SetTo(GridType.INTERNAL_RESERVED_CUR, theme)); tmp.DrawEdge(boxing, boxing.Front, Draw.SetTo(GridType.INTERNAL_RESERVED_BLOCKED, theme)); tmp.ToLog(Logs.LevelGen); } } #endregion // Place startpoints placed = options.Random(rand); obj.DrawEdge(placed, placed.Front, Draw.Around(false, Draw.IsType <GenSpace>(GridType.Floor).IfThen(Draw.SetTo(GridType.StairPlace, theme)))); return(true); }
protected void PlaceDoors() { #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.printHeader(Logs.LevelGen, "Place Doors"); } #endregion foreach (LayoutObject room in Objects) { #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.printHeader(Logs.LevelGen, "Place Doors on " + room); } #endregion var potentialDoors = new MultiMap <GenSpace>(); room.Grids.DrawPotentialExternalDoors(Draw.AddTo <GenSpace>(potentialDoors)); int numDoors = Rand.Next(doorsMin, doorsMax); #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen)) { potentialDoors.ToLog(Logs.LevelGen, "Potential Doors"); BigBoss.Debug.w(Logs.LevelGen, "Number of doors to generate: " + numDoors); } #endregion foreach (Value2D <GenSpace> doorSpace in potentialDoors.GetRandom(Rand, numDoors, minDoorSpacing)) { room.Grids.SetTo(doorSpace, GridType.Door, Theme); } #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen)) { room.ToLog(Logs.LevelGen, "Room After placing doors"); BigBoss.Debug.printFooter(Logs.LevelGen, "Place Doors on " + room); } #endregion } #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.printFooter(Logs.LevelGen, "Place Doors"); } #endregion }
public Stack <List <Value2D <T> > > Find() { #region DEBUG if (BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps) && BigBoss.Debug.logging(Logs.LevelGen) && typeof(T) == typeof(GridType)) { BigBoss.Debug.printHeader(Logs.LevelGen, "Jump Towards Search"); BigBoss.Debug.w(Logs.LevelGen, "Starting from " + curPoint + " Going towards " + gravityPt); MultiMap <GridType> tmpArr = new MultiMap <GridType>(); foreach (Value2D <T> val in container) { tmpArr[val] = (GridType)(object)container[val]; } tmpArr[curPoint.x, curPoint.y] = GridType.INTERNAL_RESERVED_CUR; tmpArr.ToLog(Logs.LevelGen, "Starting Map:"); } #endregion // Push start point onto path lastJump = new List <Value2D <T> >(new Value2D <T>[] { new Value2D <T>(curPoint.x, curPoint.y, container[curPoint]) }); pathTaken.Push(lastJump); jumps[curPoint] = new JumpSetup(this, curPoint, curPoint); try { while (pathTaken.Count > 0) { curPoint = lastJump[lastJump.Count - 1]; // Didn't find target, go towards target JumpSetup jumpSetup = jumps[curPoint]; if (GetJumpTowards(jumpSetup, out lastJump)) { // Found target pathTaken.Push(lastJump); break; } if (lastJump.Count > 0) { // Jumped // Chose a dir pathTaken.Push(lastJump); #region DEBUG if (BigBoss.Debug.Flag(DebugManager.DebugFlag.SearchSteps) && BigBoss.Debug.logging(Logs.LevelGen)) { PrintSetup(); } #endregion } else { // None found. Pop if (lastJump.Count <= 1) { pathTaken.Pop(); } else { lastJump.RemoveAt(lastJump.Count - 1); } #region DEBUG if (BigBoss.Debug.Flag(DebugManager.DebugFlag.SearchSteps) && BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.w(Logs.LevelGen, "Backing up from " + curPoint.x + " " + curPoint.y); PrintSetup(); } #endregion if (pathTaken.Count > 0) { lastJump = pathTaken.Peek(); } } } } catch (Exception ex) { BigBoss.Debug.w(Logs.LevelGen, ex.ToString()); #region DEBUG if (BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps) && BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.printFooter(Logs.LevelGen, "Jump Towards Search"); } #endregion throw; } #region DEBUG if (BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps) && BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.printFooter(Logs.LevelGen, "Jump Towards Search"); } #endregion return(pathTaken); }
protected void ClusterAround(LayoutObjectContainer cluster, LayoutObject obj) { #region Debug if (BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.printHeader("Cluster Around"); } #endregion obj.ShiftOutside(cluster, new Point(1, 0), null, false, false); obj.Shift(-1, 0); // Shift to overlapping slightly MultiMap <bool> visited = new MultiMap <bool>(); visited[0, 0] = true; ProbabilityList <ClusterInfo> shiftOptions = new ProbabilityList <ClusterInfo>(); Queue <Point> shiftQueue = new Queue <Point>(); shiftQueue.Enqueue(new Point()); Container2D <GenSpace> clusterGrid = cluster.GetGrid(); Container2D <GenSpace> objGrid = obj.GetGrid(); #region Debug if (BigBoss.Debug.logging(Logs.LevelGen)) { var tmp = new MultiMap <GenSpace>(); tmp.PutAll(obj.GetGrid()); tmp.PutAll(cluster.GetGrid()); tmp.ToLog(Logs.LevelGen, "Starting placement"); } #endregion while (shiftQueue.Count > 0) { Point curShift = shiftQueue.Dequeue(); #region Debug if (BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps) && BigBoss.Debug.logging(Logs.LevelGen)) { var tmpMap = new MultiMap <GenSpace>(); tmpMap.PutAll(clusterGrid); tmpMap.PutAll(objGrid, curShift); tmpMap.ToLog(Logs.LevelGen, "Analyzing at shift " + curShift); } #endregion // Test if pass List <Point> intersectPoints = new List <Point>(); if (objGrid.DrawAll((arr, x, y) => { if (GridTypeEnum.EdgeType(arr[x, y].GetGridType())) { GridType clusterType = clusterGrid[x + curShift.x, y + curShift.y].GetGridType(); if (clusterType == GridType.NULL) { return(true); } intersectPoints.Add(new Point(x, y)); return(GridTypeEnum.EdgeType(clusterType)); } else { return(!clusterGrid.Contains(x + curShift.x, y + curShift.y)); } }) && intersectPoints.Count > 0) { // Passed test // queue surrounding points visited.DrawAround(curShift.x, curShift.y, true, Draw.Not(Draw.EqualTo(true)).IfThen(Draw.AddTo <bool>(shiftQueue).And(Draw.SetTo(true)))); #region Debug if (BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps) && BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.w(Logs.LevelGen, "passed with " + intersectPoints.Count); } #endregion shiftOptions.Add(new ClusterInfo() { Shift = curShift, Intersects = intersectPoints }, Math.Pow(intersectPoints.Count, 3)); } } #region Debug if (BigBoss.Debug.logging(Logs.LevelGen)) { shiftOptions.ToLog(Logs.LevelGen, "Shift options"); } #endregion List <Point> clusterDoorOptions = new List <Point>(); ClusterInfo info; var placed = new List <Value2D <GenSpace> >(0); while (shiftOptions.Take(Rand, out info)) { clusterGrid.DrawPoints(info.Intersects, Draw.CanDrawDoor().IfThen(Draw.AddTo <GenSpace>(clusterDoorOptions)).Shift(info.Shift)); #region Debug if (BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.w(Logs.LevelGen, "selected " + info.Shift); var tmpMap = new MultiMap <GenSpace>(); clusterGrid.DrawAll(Draw.CopyTo(tmpMap)); objGrid.DrawAll(Draw.CopyTo(tmpMap, info.Shift)); tmpMap.DrawPoints(info.Intersects, Draw.SetTo(GridType.INTERNAL_RESERVED_CUR, Theme).Shift(info.Shift)); tmpMap.ToLog(Logs.LevelGen, "Intersect Points"); tmpMap = new MultiMap <GenSpace>(); clusterGrid.DrawAll(Draw.CopyTo(tmpMap)); objGrid.DrawAll(Draw.CopyTo(tmpMap, info.Shift)); tmpMap.DrawPoints(clusterDoorOptions, Draw.SetTo(GridType.Door, Theme)); tmpMap.ToLog(Logs.LevelGen, "Cluster door options"); } #endregion if (clusterDoorOptions.Count > 0) { // Cluster side has door options obj.Shift(info.Shift.x, info.Shift.y); placed = obj.PlaceSomeDoors(clusterDoorOptions, Theme, Rand); if (placed.Count != 0) { // Placed a door foreach (Point p in placed) { LayoutObject clusterObj; cluster.GetObjAt(p, out clusterObj); obj.Connect(clusterObj); } break; } else { #region Debug if (BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.w(Logs.LevelGen, "selected point failed to match " + info.Shift + ". Backing up"); } #endregion obj.Shift(-info.Shift.x, -info.Shift.y); } } } if (placed.Count == 0) { throw new ArgumentException("Could not cluster rooms"); } #region Debug if (BigBoss.Debug.logging(Logs.LevelGen)) { var tmpMap = new MultiMap <GenSpace>(); tmpMap.PutAll(clusterGrid); tmpMap.PutAll(obj.GetGrid()); tmpMap.ToLog(Logs.LevelGen, "Final setup " + info.Shift); BigBoss.Debug.printFooter("Cluster Around"); } #endregion }
public static void ShiftOutside(this ILayoutObject obj, ILayoutObject rhs, Point dir, Point hint, bool rough, bool finalShift) { Point reducBase = dir.Reduce(); Point reduc = new Point(reducBase); int xShift, yShift; #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.printHeader(Logs.LevelGen, "Shift Outside " + obj.ToString()); BigBoss.Debug.w(Logs.LevelGen, "Shifting outside of " + rhs.ToString()); BigBoss.Debug.w(Logs.LevelGen, "Shift " + dir + " Reduc shift: " + reduc); BigBoss.Debug.w(Logs.LevelGen, "Bounds: " + obj.Bounding + " RHS bounds: " + rhs.Bounding); var tmp = new MultiMap <GenSpace>(); tmp.PutAll(rhs.GetGrid()); tmp.PutAll(obj.GetGrid()); tmp.ToLog(Logs.LevelGen, "Before shifting"); } #endregion Point at; while (obj.Intersects(rhs, hint, out at)) { if (rough) { obj.Shift(reduc.x, reduc.y); at.Shift(reduc); hint = at; } else { reduc.Take(out xShift, out yShift); obj.Shift(xShift, yShift); if (reduc.isZero()) { reduc = new Point(reducBase); } at.Shift(xShift, yShift); hint = at; } #region DEBUG if (BigBoss.Debug.Flag(DebugManager.DebugFlag.FineSteps) && BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.w(Logs.LevelGen, "Intersected at " + at); var tmp = new MultiMap <GenSpace>(); tmp.PutAll(rhs.GetGrid()); tmp.PutAll(obj.GetGrid()); tmp.ToLog(Logs.LevelGen, "After shifting"); } #endregion } if (finalShift) { obj.Shift(dir.x, dir.y); } #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen)) { BigBoss.Debug.printFooter(Logs.LevelGen, "Shift Outside " + obj.ToString()); } #endregion }
void Prune() { #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen) && BigBoss.Debug.Flag(DebugManager.DebugFlag.LevelGen_Path_Simplify_Prune)) { BigBoss.Debug.printHeader(Logs.LevelGen, "Prune"); } #endregion Bounding bounds = new Bounding(); foreach (Value2D <GenSpace> g in List) { bounds.Absorb(g); } Array2D <int> indexes = new Array2D <int>(bounds); List <Value2D <GenSpace> > tmp = new List <Value2D <GenSpace> >(List); int index = 0; foreach (Value2D <GenSpace> val in tmp) { // For each point on the path int lastDiff = 0; Value2D <int> neighbor = null; indexes.DrawAround(val.x, val.y, false, (arr2, x, y) => { // Find neighboring point on path with the largest distance from current if (arr2[x, y] == 0) { return(true); } int valDiff = Mathf.Abs(index - arr2[x, y]); if (valDiff > 1 && // Diff meets requirements (neighbor == null || lastDiff < valDiff)) // Larger than last found diff { lastDiff = valDiff; neighbor = new Value2D <int>(x, y, arr2[x, y]); } return(true); }); #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen) && BigBoss.Debug.Flag(DebugManager.DebugFlag.LevelGen_Path_Simplify_Prune)) { BigBoss.Debug.w(Logs.LevelGen, "Evaluating " + val); if (neighbor != null) { BigBoss.Debug.w(Logs.LevelGen, "Found Neighbor " + neighbor); } } #endregion if (neighbor != null) { // If point of interest exists, prune int fromIndex = neighbor.val + 1; int count = index - neighbor.val - 1; // Set indices to 0 List <Value2D <GenSpace> > toRemove = List.GetRange(fromIndex, count); foreach (Value2D <GenSpace> r in toRemove) { indexes[r.x, r.y] = 0; } // Remove List.RemoveRange(fromIndex, count); // Set next index to proper number index = neighbor.val + 1; #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen) && BigBoss.Debug.Flag(DebugManager.DebugFlag.LevelGen_Path_Simplify_Prune)) { BigBoss.Debug.w(Logs.LevelGen, "Removed index: " + fromIndex + " count: " + count); MultiMap <GridType> map = new MultiMap <GridType>(); foreach (var v in List) { map[v] = v.val.Type; } map.ToLog(Logs.LevelGen); } #endregion } indexes[val.x, val.y] = index; index++; } #region DEBUG if (BigBoss.Debug.logging(Logs.LevelGen) && BigBoss.Debug.Flag(DebugManager.DebugFlag.LevelGen_Path_Simplify_Prune)) { BigBoss.Debug.printFooter(Logs.LevelGen, "Prune"); } #endregion }