public void DirFromAxis(Axis4 axis, int scalar, Dir4 expected, bool exception = false) { if (exception) { Assert.Throws <ArgumentOutOfRangeException>(() => { axis.GetDir(scalar); }); } else { Assert.That(axis.GetDir(scalar), Is.EqualTo(expected)); } }
public void ToAxis8(Axis4 axis, Axis8 expected, bool exception = false) { if (exception) { Assert.Throws <ArgumentOutOfRangeException>(() => { axis.ToAxis8(); }); } else { Assert.That(axis.ToAxis8(), Is.EqualTo(expected)); } }
public static bool Validate(this Axis4 axis) { switch (axis) { case Axis4.None: case Axis4.Horiz: case Axis4.Vert: return(true); default: return(false); } }
public static Loc CreateLoc(this Axis4 axis, int scalar, int orth) { switch (axis) { case Axis4.Vert: return(new Loc(orth, scalar)); case Axis4.Horiz: return(new Loc(scalar, orth)); case Axis4.None: throw new ArgumentException($"Cannot create {nameof(Loc)} from axis {nameof(Axis4.None)}.", nameof(axis)); default: throw new ArgumentOutOfRangeException(nameof(axis), axis, "Invalid enum value."); } }
/// <summary> /// Gets the orthogonal axis to this 4-directional axis. /// </summary> /// <param name="axis"></param> /// <returns></returns> public static Axis4 Orth(this Axis4 axis) { switch (axis) { case Axis4.None: return(Axis4.None); case Axis4.Vert: return(Axis4.Horiz); case Axis4.Horiz: return(Axis4.Vert); default: throw new ArgumentOutOfRangeException(nameof(axis), axis, "Invalid enum value."); } }
public static int GetScalar(this Loc loc, Axis4 axis) { switch (axis) { case Axis4.Vert: return(loc.Y); case Axis4.Horiz: return(loc.X); case Axis4.None: throw new ArgumentException($"Cannot get scalar on axis {nameof(Axis4.None)}.", nameof(axis)); default: throw new ArgumentOutOfRangeException(nameof(axis), axis, "Invalid enum value."); } }
public void ScalarFromAxis(int locX, int locY, Axis4 axis, int expected, bool exception = false) { if (exception) { if (axis == Axis4.None) { Assert.Throws <ArgumentException>(() => { new Loc(locX, locY).GetScalar(axis); }); } else { Assert.Throws <ArgumentOutOfRangeException>(() => { new Loc(locX, locY).GetScalar(axis); }); } } else { Assert.That(new Loc(locX, locY).GetScalar(axis), Is.EqualTo(expected)); } }
public void FromAxisScalar(Axis4 axis, int scalar, int expectedX, int expectedY, bool exception = false) { if (exception) { if (axis == Axis4.None) { Assert.Throws <ArgumentException>(() => { axis.CreateLoc(scalar, 0); }); } else { Assert.Throws <ArgumentOutOfRangeException>(() => { axis.CreateLoc(scalar, 0); }); } } else { Assert.That(axis.CreateLoc(scalar, 0), Is.EqualTo(new Loc(expectedX, expectedY))); } }
public static Dir4 GetDir(this Axis4 axis, int scalar) { if (scalar == 0 & axis.Validate()) { return(Dir4.None); } else { switch (axis) { case Axis4.None: return(Dir4.None); case Axis4.Horiz: return(scalar < 0 ? Dir4.Left : Dir4.Right); case Axis4.Vert: return(scalar < 0 ? Dir4.Up : Dir4.Down); default: throw new ArgumentOutOfRangeException(nameof(axis), axis, "Invalid enum value."); } } }
protected LocRay4?PlaceRoom(T map, List <LocRay4> rays, EffectTile sealingTile, List <Loc> freeTiles) { Grid.LocTest checkBlockForPlace = (Loc testLoc) => { if (!Collision.InBounds(map.Width, map.Height, testLoc)) { return(false); } return(!map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) && !map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.UnbreakableTerrain)); }; //try X times to dig a passage for (int ii = 0; ii < 500 && rays.Count > 0; ii++) { int rayIndex = map.Rand.Next(rays.Count); LocRay4 ray = rays[rayIndex]; rays.RemoveAt(rayIndex); Loc rayDirLoc = ray.Dir.GetLoc(); Axis4 axis = ray.Dir.ToAxis(); Axis4 orth = axis == Axis4.Horiz ? Axis4.Vert : Axis4.Horiz; int minLength = Math.Max(1, HallLength.Min); Rect hallBound = new Rect(ray.Loc + DirExt.AddAngles(ray.Dir, Dir4.Left).GetLoc(), new Loc(1)); hallBound = Rect.IncludeLoc(hallBound, ray.Loc + rayDirLoc * (minLength - 1) + DirExt.AddAngles(ray.Dir, Dir4.Right).GetLoc()); //make sure the MIN hall can tunnel unimpeded if (!CanPlaceRect(map, hallBound, checkBlockForPlace)) { continue; } for (int jj = 0; jj < 100; jj++) { //plan the room RoomGen <T> plan = GenericRooms.Pick(map.Rand).Copy(); Loc size = plan.ProposeSize(map.Rand); plan.PrepareSize(map.Rand, size); //attempt to place the bounds somewhere, anywhere, within the limitations that the room itself provides List <int> candidateOpenings = new List <int>(); int planLength = plan.GetBorderLength(ray.Dir.Reverse()); for (int kk = 0; kk < planLength; kk++) { if (plan.GetFulfillableBorder(ray.Dir.Reverse(), kk)) { candidateOpenings.Add(kk); } } //as well as continue extending the hall until we hit a walkable. int tunnelLen = Math.Max(1, HallLength.Pick(map.Rand)); Loc roomLoc = ray.Loc + rayDirLoc * tunnelLen; int perpOffset = candidateOpenings[map.Rand.Next(candidateOpenings.Count)]; roomLoc += orth.CreateLoc(-perpOffset, 0); if (rayDirLoc.GetScalar(axis) < 0)//move back the top-left of the entrance { roomLoc += rayDirLoc * (size.GetScalar(axis) - 1); } Rect roomTestBound = new Rect(roomLoc, size); roomTestBound.Inflate(1, 1); //make a rect for the rest of the hall Rect hallExtBound = new Rect(ray.Loc + rayDirLoc * minLength + DirExt.AddAngles(ray.Dir, Dir4.Left).GetLoc(), new Loc(1)); hallExtBound = Rect.IncludeLoc(hallBound, ray.Loc + rayDirLoc * (tunnelLen - 1) + DirExt.AddAngles(ray.Dir, Dir4.Right).GetLoc()); //now that we've chosen our position, let's test it if (!CanPlaceRect(map, roomTestBound, checkBlockForPlace) || !CanPlaceRect(map, hallExtBound, checkBlockForPlace)) // also test that the CHOSEN hallway can be properly sealed { continue; //invalid location, try another place } else { plan.SetLoc(roomLoc); plan.ReceiveBorderRange(new IntRange(perpOffset, perpOffset + 1) + roomLoc.GetScalar(orth), ray.Dir.Reverse()); //draw the room plan.DrawOnMap(map); //surround the room with bounds for (int xx = roomTestBound.X; xx < roomTestBound.Right; xx++) { map.Tiles[xx][roomTestBound.Y] = (Tile)map.UnbreakableTerrain.Copy(); map.Tiles[xx][roomTestBound.End.Y - 1] = (Tile)map.UnbreakableTerrain.Copy(); } for (int yy = roomTestBound.Y + 1; yy < roomTestBound.Bottom - 1; yy++) { map.Tiles[roomTestBound.X][yy] = (Tile)map.UnbreakableTerrain.Copy(); map.Tiles[roomTestBound.End.X - 1][yy] = (Tile)map.UnbreakableTerrain.Copy(); } //spawn tiles, items, foes List <Loc> addedTiles = ((IPlaceableGenContext <MapItem>)map).GetFreeTiles(plan.Draw); freeTiles.AddRange(addedTiles); //tunnel to the room Loc loc = ray.Loc; for (int tt = 0; tt < tunnelLen; tt++) { //make walkable map.Tiles[loc.X][loc.Y] = (Tile)map.RoomTerrain.Copy(); //make left side unbreakable Loc lLoc = loc + DirExt.AddAngles(ray.Dir, Dir4.Left).GetLoc(); map.Tiles[lLoc.X][lLoc.Y] = (Tile)map.UnbreakableTerrain.Copy(); //make right side unbreakable Loc rLoc = loc + DirExt.AddAngles(ray.Dir, Dir4.Right).GetLoc(); map.Tiles[rLoc.X][rLoc.Y] = (Tile)map.UnbreakableTerrain.Copy(); loc += rayDirLoc; } //finally, seal with a locked door map.Tiles[ray.Loc.X][ray.Loc.Y] = (Tile)map.UnbreakableTerrain.Copy(); EffectTile newEffect = new EffectTile(sealingTile, ray.Loc); ((IPlaceableGenContext <EffectTile>)map).PlaceItem(ray.Loc, newEffect); return(ray); } } } //DiagManager.Instance.LogInfo("Couldn't place sealed detour!"); return(null); }
public void PlaceOrientedHall(Axis4 axis, int scalar, int orth, int scalarDiff, GridPlan floorPlan, PermissiveRoomGen <T> hallGen) { Loc loc = this.GapAxis.CreateLoc(scalar, orth); floorPlan.SetHall(new LocRay4(loc, axis.GetDir(scalarDiff)), hallGen, this.HallComponents.Clone()); }