Example #1
0
 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));
     }
 }
Example #2
0
 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));
     }
 }
Example #3
0
        public static bool Validate(this Axis4 axis)
        {
            switch (axis)
            {
            case Axis4.None:
            case Axis4.Horiz:
            case Axis4.Vert:
                return(true);

            default:
                return(false);
            }
        }
Example #4
0
        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.");
            }
        }
Example #5
0
        /// <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.");
            }
        }
Example #6
0
        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.");
            }
        }
Example #7
0
 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));
     }
 }
Example #8
0
 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)));
     }
 }
Example #9
0
        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.");
                }
            }
        }
Example #10
0
        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);
        }
Example #11
0
        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());
        }