|  |  |  | @ -13,7 +13,7 @@ import mightypork.rogue.world.level.Level; | 
			
		
	
		
			
				
					|  |  |  |  | import mightypork.rogue.world.tile.Tile; | 
			
		
	
		
			
				
					|  |  |  |  | import mightypork.rogue.world.tile.TileModel; | 
			
		
	
		
			
				
					|  |  |  |  | import mightypork.rogue.world.tile.Tiles; | 
			
		
	
		
			
				
					|  |  |  |  | import mightypork.utils.Support; | 
			
		
	
		
			
				
					|  |  |  |  | import mightypork.utils.Str; | 
			
		
	
		
			
				
					|  |  |  |  | import mightypork.utils.logging.Log; | 
			
		
	
		
			
				
					|  |  |  |  | import mightypork.utils.math.Calc; | 
			
		
	
		
			
				
					|  |  |  |  | import mightypork.utils.math.algo.Coord; | 
			
		
	
	
		
			
				
					|  |  |  | @ -29,21 +29,21 @@ import mightypork.utils.math.algo.pathfinding.PathFinder; | 
			
		
	
		
			
				
					|  |  |  |  |  * @author Ondřej Hruška (MightyPork) | 
			
		
	
		
			
				
					|  |  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  |  | public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	private Tile[][] map; | 
			
		
	
		
			
				
					|  |  |  |  | 	private final int width; | 
			
		
	
		
			
				
					|  |  |  |  | 	private final int height; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	private final List<RoomEntry> rooms = new ArrayList<>(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	/** Coords to connect with corridors */ | 
			
		
	
		
			
				
					|  |  |  |  | 	private final List<Coord> nodes = new ArrayList<>(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	private final List<Coord> occupied = new ArrayList<>(); | 
			
		
	
		
			
				
					|  |  |  |  | 	private final List<Entity> entities = new ArrayList<>(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	private final PathFinder pathf = new PathFinder() { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		@Override | 
			
		
	
		
			
				
					|  |  |  |  | 		public boolean isAccessible(Coord pos) | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
	
		
			
				
					|  |  |  | @ -52,109 +52,109 @@ public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 			if (t.isStairs()) return false; | 
			
		
	
		
			
				
					|  |  |  |  | 			return t.isPotentiallyWalkable() || (t.genData.protection != TileProtectLevel.STRONG); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		@Override | 
			
		
	
		
			
				
					|  |  |  |  | 		public int getCost(Coord last, Coord pos) | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			final Tile t = getTile(pos); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			 | 
			
		
	
		
			
				
					|  |  |  |  | 			switch (t.getType()) { | 
			
		
	
		
			
				
					|  |  |  |  | 				case NULL: | 
			
		
	
		
			
				
					|  |  |  |  | 					return 60; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 				case DOOR: | 
			
		
	
		
			
				
					|  |  |  |  | 				case PASSAGE: | 
			
		
	
		
			
				
					|  |  |  |  | 					return 10; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 				case STAIRS: | 
			
		
	
		
			
				
					|  |  |  |  | 				case FLOOR: | 
			
		
	
		
			
				
					|  |  |  |  | 					return 20; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 				case WALL: | 
			
		
	
		
			
				
					|  |  |  |  | 					if (t.genData.protection != TileProtectLevel.NONE) return 2000; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 					return 100; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 				default: | 
			
		
	
		
			
				
					|  |  |  |  | 					throw new WorldGenError("Unknown tile type: " + t.getType()); | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		@Override | 
			
		
	
		
			
				
					|  |  |  |  | 		public int getMinCost() | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			return 10; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		@Override | 
			
		
	
		
			
				
					|  |  |  |  | 		public Heuristic getHeuristic() | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			return PathFinder.CORNER_HEURISTIC; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		@Override | 
			
		
	
		
			
				
					|  |  |  |  | 		public List<Move> getWalkSides() | 
			
		
	
		
			
				
					|  |  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  |  | 			return Moves.CARDINAL_SIDES; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 	}; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		// needed for when the path starts / ends at stairs.
 | 
			
		
	
		
			
				
					|  |  |  |  | 		pathf.setIgnoreEnd(true); | 
			
		
	
		
			
				
					|  |  |  |  | 		pathf.setIgnoreStart(true); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	Coord genMin; | 
			
		
	
		
			
				
					|  |  |  |  | 	Coord genMax; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	private final MapTheme theme; | 
			
		
	
		
			
				
					|  |  |  |  | 	private final Random rand; | 
			
		
	
		
			
				
					|  |  |  |  | 	private final Coord enterPoint = new Coord(); | 
			
		
	
		
			
				
					|  |  |  |  | 	private final Coord exitPoint = new Coord(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	private static final boolean FIX_GLITCHES = true; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public ScratchMap(int max_size, MapTheme theme, Random rand) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		map = new Tile[max_size][max_size]; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		genMin = Coord.make((max_size / 2) - 1, (max_size / 2) - 1); | 
			
		
	
		
			
				
					|  |  |  |  | 		genMax = genMin.add(1, 1); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		width = max_size; | 
			
		
	
		
			
				
					|  |  |  |  | 		height = max_size; | 
			
		
	
		
			
				
					|  |  |  |  | 		this.rand = rand; | 
			
		
	
		
			
				
					|  |  |  |  | 		this.theme = theme; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		fill(Coord.make(0, 0), Coord.make(width - 1, height - 1), Tiles.NULL); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public void addRoom(RoomBuilder rb, boolean critical) throws WorldGenError | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		try { | 
			
		
	
		
			
				
					|  |  |  |  | 			if (rooms.size() > 0) minimizeBounds(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			 | 
			
		
	
		
			
				
					|  |  |  |  | 			final Coord roomPos = Coord.make(0, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			 | 
			
		
	
		
			
				
					|  |  |  |  | 			int failed = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 			int failed_total = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			 | 
			
		
	
		
			
				
					|  |  |  |  | 			while (true) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				final int sizeX = genMax.x - genMin.x; | 
			
		
	
		
			
				
					|  |  |  |  | 				final int sizeY = genMax.y - genMin.y; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				roomPos.x = genMin.x + rand.nextInt(sizeX + 1); | 
			
		
	
		
			
				
					|  |  |  |  | 				roomPos.y = genMin.y + rand.nextInt(sizeY + 1); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				switch (rand.nextInt(4)) { | 
			
		
	
		
			
				
					|  |  |  |  | 					case 0: | 
			
		
	
		
			
				
					|  |  |  |  | 						roomPos.x += (failed_total / 35); | 
			
		
	
	
		
			
				
					|  |  |  | @ -168,47 +168,47 @@ public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 					case 3: | 
			
		
	
		
			
				
					|  |  |  |  | 						roomPos.y -= (failed_total / 35); | 
			
		
	
		
			
				
					|  |  |  |  | 				} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				final RoomEntry rd = rb.buildRoom(this, theme, rand, roomPos); | 
			
		
	
		
			
				
					|  |  |  |  | 				if (rd != null) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 					rooms.add(rd); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 					genMin.x = Math.min(genMin.x, rd.min.x); | 
			
		
	
		
			
				
					|  |  |  |  | 					genMin.y = Math.min(genMin.y, rd.min.y); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 					genMax.x = Math.max(genMax.x, rd.max.x); | 
			
		
	
		
			
				
					|  |  |  |  | 					genMax.y = Math.max(genMax.y, rd.max.y); | 
			
		
	
		
			
				
					|  |  |  |  | 					clampBounds(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 					nodes.add(roomPos); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 					return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 				} else { | 
			
		
	
		
			
				
					|  |  |  |  | 					failed++; | 
			
		
	
		
			
				
					|  |  |  |  | 					failed_total++; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 					if (failed_total > 1000) { | 
			
		
	
		
			
				
					|  |  |  |  | 						throw new WorldGenError("Failed to add a room."); | 
			
		
	
		
			
				
					|  |  |  |  | 					} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 					if (failed > 300) { | 
			
		
	
		
			
				
					|  |  |  |  | 						Log.w("Faild to build room."); | 
			
		
	
		
			
				
					|  |  |  |  | 						if (critical) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 							 | 
			
		
	
		
			
				
					|  |  |  |  | 							// expand gen bounds
 | 
			
		
	
		
			
				
					|  |  |  |  | 							genMin.x -= 5; | 
			
		
	
		
			
				
					|  |  |  |  | 							genMin.y -= 5; | 
			
		
	
		
			
				
					|  |  |  |  | 							genMax.x += 5; | 
			
		
	
		
			
				
					|  |  |  |  | 							genMax.y += 5; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 							 | 
			
		
	
		
			
				
					|  |  |  |  | 							clampBounds(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 							 | 
			
		
	
		
			
				
					|  |  |  |  | 							failed = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 							Log.f3("Trying again."); | 
			
		
	
		
			
				
					|  |  |  |  | 							continue; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 							 | 
			
		
	
		
			
				
					|  |  |  |  | 						} else { | 
			
		
	
		
			
				
					|  |  |  |  | 							throw new WorldGenError("Failed to add a room."); | 
			
		
	
		
			
				
					|  |  |  |  | 						} | 
			
		
	
	
		
			
				
					|  |  |  | @ -225,8 +225,8 @@ public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	/** | 
			
		
	
		
			
				
					|  |  |  |  | 	 * Clamp bounds to available area | 
			
		
	
		
			
				
					|  |  |  |  | 	 */ | 
			
		
	
	
		
			
				
					|  |  |  | @ -237,8 +237,8 @@ public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 		genMax.x = Calc.clamp(genMax.x, 0, width - 1); | 
			
		
	
		
			
				
					|  |  |  |  | 		genMax.y = Calc.clamp(genMax.y, 0, height - 1); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	/** | 
			
		
	
		
			
				
					|  |  |  |  | 	 * Minimize gen bounds based on defined room bounds | 
			
		
	
		
			
				
					|  |  |  |  | 	 */ | 
			
		
	
	
		
			
				
					|  |  |  | @ -246,124 +246,124 @@ public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		final Coord low = Coord.make(width, height); | 
			
		
	
		
			
				
					|  |  |  |  | 		final Coord high = Coord.make(0, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		for (final RoomEntry rd : rooms) { | 
			
		
	
		
			
				
					|  |  |  |  | 			low.x = Math.min(low.x, rd.min.x); | 
			
		
	
		
			
				
					|  |  |  |  | 			low.y = Math.min(low.y, rd.min.y); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			 | 
			
		
	
		
			
				
					|  |  |  |  | 			high.x = Math.max(high.x, rd.max.x); | 
			
		
	
		
			
				
					|  |  |  |  | 			high.y = Math.max(high.y, rd.max.y); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		genMin.setTo(low); | 
			
		
	
		
			
				
					|  |  |  |  | 		genMax.setTo(high); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public boolean isIn(Coord pos) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		return pos.x >= 0 && pos.x < width && pos.y >= 0 && pos.y < height; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public Tile getTile(Coord pos) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!isIn(pos)) { | 
			
		
	
		
			
				
					|  |  |  |  | 			throw new WorldGenError("Tile not in map: " + pos); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		return map[pos.y][pos.x]; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public boolean set(Coord pos, TileModel tm) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		return set(pos, tm.createTile()); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public boolean set(Coord pos, Tile tile) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!isIn(pos)) { | 
			
		
	
		
			
				
					|  |  |  |  | 			throw new WorldGenError("Tile not in map: " + pos); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		map[pos.y][pos.x] = tile; | 
			
		
	
		
			
				
					|  |  |  |  | 		return true; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public boolean isClear(Coord min, Coord max) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!isIn(min) || !isIn(max)) return false; | 
			
		
	
		
			
				
					|  |  |  |  | 		for (final RoomEntry r : rooms) { | 
			
		
	
		
			
				
					|  |  |  |  | 			if (r.intersectsWith(min, max)) return false; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		return true; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public void protect(Coord pos, TileProtectLevel prot) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		protect(pos, pos, prot); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public void protect(Coord min, Coord max, TileProtectLevel prot) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!isIn(min) || !isIn(max)) throw new WorldGenError("Tile(s) not in map: " + min + " , " + max); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		final Coord c = Coord.make(0, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 		for (c.x = min.x; c.x <= max.x; c.x++) | 
			
		
	
		
			
				
					|  |  |  |  | 			for (c.y = min.y; c.y <= max.y; c.y++) | 
			
		
	
		
			
				
					|  |  |  |  | 				getTile(c).genData.protection = prot; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public void fill(Coord min, Coord max, TileModel tm) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!isIn(min) || !isIn(max)) throw new WorldGenError("Tile(s) not in map: " + min + " , " + max); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		final Coord c = Coord.make(0, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 		for (c.x = min.x; c.x <= max.x; c.x++) | 
			
		
	
		
			
				
					|  |  |  |  | 			for (c.y = min.y; c.y <= max.y; c.y++) | 
			
		
	
		
			
				
					|  |  |  |  | 				set(c, tm.createTile()); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public void border(Coord min, Coord max, TileModel tm) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!isIn(min) || !isIn(max)) throw new WorldGenError("Tile(s) not in map: " + min + " , " + max); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		final Coord c = Coord.make(0, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		// top
 | 
			
		
	
		
			
				
					|  |  |  |  | 		for (c.x = min.x, c.y = min.y; c.x <= max.x; c.x++) | 
			
		
	
		
			
				
					|  |  |  |  | 			set(c, tm.createTile()); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		//bottom
 | 
			
		
	
		
			
				
					|  |  |  |  | 		for (c.x = min.x, c.y = max.y; c.x <= max.x; c.x++) | 
			
		
	
		
			
				
					|  |  |  |  | 			set(c, tm.createTile()); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		//left
 | 
			
		
	
		
			
				
					|  |  |  |  | 		for (c.x = min.x, c.y = min.y + 1; c.y < max.y; c.y++) | 
			
		
	
		
			
				
					|  |  |  |  | 			set(c, tm.createTile()); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		//right
 | 
			
		
	
		
			
				
					|  |  |  |  | 		for (c.x = max.x, c.y = min.y + 1; c.y < max.y; c.y++) | 
			
		
	
		
			
				
					|  |  |  |  | 			set(c, tm.createTile()); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public void buildCorridors() | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | //		Log.f3("Building corridors.");
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		Coord start = nodes.get(0); | 
			
		
	
		
			
				
					|  |  |  |  | 		final Set<Coord> starts = new HashSet<>(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		for (int i = 0; i < 2 + rooms.size() / 5; i++) { | 
			
		
	
		
			
				
					|  |  |  |  | 			if (!starts.contains(start)) { | 
			
		
	
		
			
				
					|  |  |  |  | 				for (int j = 0; j < nodes.size(); j++) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -374,24 +374,24 @@ public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 			start = Calc.pick(rand, nodes); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	private void buildCorridor(Coord node1, Coord node2) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | //		Log.f3("Building corridor " + node1 + " -> " + node2);
 | 
			
		
	
		
			
				
					|  |  |  |  | 		final List<Coord> steps = pathf.findPath(node1, node2); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		if (steps == null) { | 
			
		
	
		
			
				
					|  |  |  |  | 			Log.w("Could not build corridor " + node1 + "->" + node2); | 
			
		
	
		
			
				
					|  |  |  |  | 			return; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		for (final Coord c : steps) { | 
			
		
	
		
			
				
					|  |  |  |  | 			buildCorridorPiece(c); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	private void buildCorridorPiece(Coord pos) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		final Coord c = Coord.make(0, 0); | 
			
		
	
	
		
			
				
					|  |  |  | @ -399,17 +399,17 @@ public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 		for (i = -1, c.x = pos.x - 1; c.x <= pos.x + 1; c.x++, i++) { | 
			
		
	
		
			
				
					|  |  |  |  | 			for (j = -1, c.y = pos.y - 1; c.y <= pos.y + 1; c.y++, j++) { | 
			
		
	
		
			
				
					|  |  |  |  | 				if (!isIn(c)) continue; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				genMin.x = Math.min(genMin.x, c.x); | 
			
		
	
		
			
				
					|  |  |  |  | 				genMin.y = Math.min(genMin.y, c.y); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				genMax.x = Math.max(genMax.x, c.x); | 
			
		
	
		
			
				
					|  |  |  |  | 				genMax.y = Math.max(genMax.y, c.y); | 
			
		
	
		
			
				
					|  |  |  |  | 				clampBounds(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				final Tile current = getTile(c); | 
			
		
	
		
			
				
					|  |  |  |  | 				if (!current.isNull() && (current.isPotentiallyWalkable() || current.isStairs())) continue; // floor already, let it be
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				if (i == 0 && j == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 					set(c, theme.floor()); | 
			
		
	
		
			
				
					|  |  |  |  | 				} else { | 
			
		
	
	
		
			
				
					|  |  |  | @ -419,8 +419,8 @@ public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	/** | 
			
		
	
		
			
				
					|  |  |  |  | 	 * @return dimensions of the area taken by non-null tiles | 
			
		
	
		
			
				
					|  |  |  |  | 	 */ | 
			
		
	
	
		
			
				
					|  |  |  | @ -428,141 +428,141 @@ public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		return Coord.make(genMax.x - genMin.x + 1, genMax.y - genMin.y + 1); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public byte findWalls(Coord pos) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		byte walls = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 		for (int i = 0; i < 8; i++) { | 
			
		
	
		
			
				
					|  |  |  |  | 			final Coord cc = pos.add(Moves.getSide(i)); | 
			
		
	
		
			
				
					|  |  |  |  | 			if (!isIn(cc)) continue; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			 | 
			
		
	
		
			
				
					|  |  |  |  | 			if (getTile(cc).isWall()) { | 
			
		
	
		
			
				
					|  |  |  |  | 				walls |= Moves.getBit(i); | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		return walls; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public byte findFloors(Coord pos) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		byte floors = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 		for (int i = 0; i <= 7; i++) { | 
			
		
	
		
			
				
					|  |  |  |  | 			final Coord cc = pos.add(Moves.getSide(i)); | 
			
		
	
		
			
				
					|  |  |  |  | 			if (!isIn(cc)) continue; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			 | 
			
		
	
		
			
				
					|  |  |  |  | 			if (getTile(cc).isFloor()) { | 
			
		
	
		
			
				
					|  |  |  |  | 				floors |= Moves.getBit(i); | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		return floors; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public byte findDoors(Coord pos) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		byte doors = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 		for (int i = 0; i <= 7; i++) { | 
			
		
	
		
			
				
					|  |  |  |  | 			final Coord cc = pos.add(Moves.getSide(i)); | 
			
		
	
		
			
				
					|  |  |  |  | 			if (!isIn(cc)) continue; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			 | 
			
		
	
		
			
				
					|  |  |  |  | 			if (getTile(cc).isDoor()) { | 
			
		
	
		
			
				
					|  |  |  |  | 				doors |= Moves.getBit(i); | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		return doors; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public byte findNils(Coord pos) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		byte nils = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 		for (int i = 0; i <= 7; i++) { | 
			
		
	
		
			
				
					|  |  |  |  | 			final Coord cc = pos.add(Moves.getSide(i)); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			 | 
			
		
	
		
			
				
					|  |  |  |  | 			if (!isIn(cc) || getTile(cc).isNull()) { | 
			
		
	
		
			
				
					|  |  |  |  | 				nils |= Moves.getBit(i); | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		return nils; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	/** | 
			
		
	
		
			
				
					|  |  |  |  | 	 * Fix generator glitches and reduce size to the actual used size | 
			
		
	
		
			
				
					|  |  |  |  | 	 */ | 
			
		
	
		
			
				
					|  |  |  |  | 	public void fixGlitches() | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		final Tile[][] out = new Tile[height][width]; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		// bounds will be adjusted by the actual tiles in the map
 | 
			
		
	
		
			
				
					|  |  |  |  | 		genMin.x = width; | 
			
		
	
		
			
				
					|  |  |  |  | 		genMin.y = height; | 
			
		
	
		
			
				
					|  |  |  |  | 		genMax.x = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 		genMax.y = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		final Coord c = Coord.make(0, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 		for (c.x = 0; c.x < width; c.x++) { | 
			
		
	
		
			
				
					|  |  |  |  | 			for (c.y = 0; c.y < height; c.y++) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				final Tile t = getTile(c); | 
			
		
	
		
			
				
					|  |  |  |  | 				final boolean isNull = t.isNull(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				final boolean isDoor = !isNull && t.isDoor(); | 
			
		
	
		
			
				
					|  |  |  |  | 				final boolean isFloor = !isNull && t.isFloor(); | 
			
		
	
		
			
				
					|  |  |  |  | 				final boolean isWall = !isNull && t.isWall(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				// bitmasks
 | 
			
		
	
		
			
				
					|  |  |  |  | 				final byte walls = findWalls(c); | 
			
		
	
		
			
				
					|  |  |  |  | 				final byte nils = findNils(c); | 
			
		
	
		
			
				
					|  |  |  |  | 				final byte floors = findFloors(c); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				boolean toWall = false; | 
			
		
	
		
			
				
					|  |  |  |  | 				boolean toFloor = false; | 
			
		
	
		
			
				
					|  |  |  |  | 				boolean toNull = false; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				do { | 
			
		
	
		
			
				
					|  |  |  |  | 					if (isWall && floors == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 						toNull = true; | 
			
		
	
		
			
				
					|  |  |  |  | 						break; | 
			
		
	
		
			
				
					|  |  |  |  | 					} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 					if (isFloor && (nils & Moves.BITS_CARDINAL) != 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 						toWall = true; // floor with adjacent cardinal null
 | 
			
		
	
		
			
				
					|  |  |  |  | 						break; | 
			
		
	
		
			
				
					|  |  |  |  | 					} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 					if (isNull && (floors & Moves.BITS_DIAGONAL) != 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 						toWall = true; // null with adjacent diagonal floor
 | 
			
		
	
		
			
				
					|  |  |  |  | 						break; | 
			
		
	
		
			
				
					|  |  |  |  | 					} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 					if (isDoor) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 						 | 
			
		
	
		
			
				
					|  |  |  |  | 						if (Calc.countBits((byte) (floors & Moves.BITS_CARDINAL)) < 2) { | 
			
		
	
		
			
				
					|  |  |  |  | 							toWall = true; | 
			
		
	
		
			
				
					|  |  |  |  | 							break; | 
			
		
	
		
			
				
					|  |  |  |  | 						} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 						 | 
			
		
	
		
			
				
					|  |  |  |  | 						if (Calc.countBits((byte) (walls & Moves.BITS_CARDINAL)) > 2) { | 
			
		
	
		
			
				
					|  |  |  |  | 							toWall = true; | 
			
		
	
		
			
				
					|  |  |  |  | 							break; | 
			
		
	
		
			
				
					|  |  |  |  | 						} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 						 | 
			
		
	
		
			
				
					|  |  |  |  | 						if (Calc.countBits((byte) (floors & Moves.BITS_CARDINAL)) > 2) { | 
			
		
	
		
			
				
					|  |  |  |  | 							toFloor = true; | 
			
		
	
		
			
				
					|  |  |  |  | 							break; | 
			
		
	
		
			
				
					|  |  |  |  | 						} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 						 | 
			
		
	
		
			
				
					|  |  |  |  | 						if ((floors & Moves.BITS_NW_CORNER) == Moves.BITS_NW_CORNER) toWall = true; | 
			
		
	
		
			
				
					|  |  |  |  | 						if ((floors & Moves.BITS_NE_CORNER) == Moves.BITS_NE_CORNER) toWall = true; | 
			
		
	
		
			
				
					|  |  |  |  | 						if ((floors & Moves.BITS_SW_CORNER) == Moves.BITS_SW_CORNER) toWall = true; | 
			
		
	
		
			
				
					|  |  |  |  | 						if ((floors & Moves.BITS_SE_CORNER) == Moves.BITS_SE_CORNER) toWall = true; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 						 | 
			
		
	
		
			
				
					|  |  |  |  | 					} | 
			
		
	
		
			
				
					|  |  |  |  | 				} while (false); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				if (toNull) { | 
			
		
	
		
			
				
					|  |  |  |  | 					out[c.y][c.x] = Tiles.NULL.createTile(); | 
			
		
	
		
			
				
					|  |  |  |  | 				} else if (toWall) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -572,21 +572,21 @@ public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 				} else { | 
			
		
	
		
			
				
					|  |  |  |  | 					out[c.y][c.x] = map[c.y][c.x]; | 
			
		
	
		
			
				
					|  |  |  |  | 				} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 				 | 
			
		
	
		
			
				
					|  |  |  |  | 				if (!out[c.y][c.x].isNull()) { | 
			
		
	
		
			
				
					|  |  |  |  | 					genMin.x = Math.min(genMin.x, c.x); | 
			
		
	
		
			
				
					|  |  |  |  | 					genMin.y = Math.min(genMin.y, c.y); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 					 | 
			
		
	
		
			
				
					|  |  |  |  | 					genMax.x = Math.max(genMax.x, c.x); | 
			
		
	
		
			
				
					|  |  |  |  | 					genMax.y = Math.max(genMax.y, c.y); | 
			
		
	
		
			
				
					|  |  |  |  | 				} | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		map = out; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	/** | 
			
		
	
		
			
				
					|  |  |  |  | 	 * Write tiles and entities into a level | 
			
		
	
		
			
				
					|  |  |  |  | 	 * | 
			
		
	
	
		
			
				
					|  |  |  | @ -597,23 +597,23 @@ public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 		if (level.getWorld() == null) { | 
			
		
	
		
			
				
					|  |  |  |  | 			throw new WorldGenError("Level has no world assigned."); // need for entities
 | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		// make sure no walkable are at edges.
 | 
			
		
	
		
			
				
					|  |  |  |  | 		final Coord c = Coord.make(0, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 		final Coord c1 = Coord.make(0, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		for (c.x = genMin.x, c1.x = 0; c.x <= genMax.x; c.x++, c1.x++) { | 
			
		
	
		
			
				
					|  |  |  |  | 			for (c.y = genMin.y, c1.y = 0; c.y <= genMax.y; c.y++, c1.y++) { | 
			
		
	
		
			
				
					|  |  |  |  | 				level.setTile(c1, getTile(c)); | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		final Coord entrance = new Coord(enterPoint.x - genMin.x, enterPoint.y - genMin.y); | 
			
		
	
		
			
				
					|  |  |  |  | 		level.setEnterPoint(entrance); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		final Coord exit = new Coord(exitPoint.x - genMin.x, exitPoint.y - genMin.y); | 
			
		
	
		
			
				
					|  |  |  |  | 		level.setExitPoint(exit); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		for (final Entity e : entities) { | 
			
		
	
		
			
				
					|  |  |  |  | 			final Coord pos = e.getCoord().add(-genMin.x, -genMin.y); | 
			
		
	
		
			
				
					|  |  |  |  | 			if (!level.addEntityNear(e, pos)) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -621,7 +621,7 @@ public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 				//@formatter:off
 | 
			
		
	
		
			
				
					|  |  |  |  | 				throw new WorldGenError( | 
			
		
	
		
			
				
					|  |  |  |  | 						"Could not put entity into a level map: e_pos="	+ pos | 
			
		
	
		
			
				
					|  |  |  |  | 						+ ", tile: " + Support.str(t) | 
			
		
	
		
			
				
					|  |  |  |  | 						+ ", tile: " + Str.val(t) | 
			
		
	
		
			
				
					|  |  |  |  | 						+ ", t.wa " + t.isWalkable() | 
			
		
	
		
			
				
					|  |  |  |  | 						+ ", t.oc " + t.isOccupied() | 
			
		
	
		
			
				
					|  |  |  |  | 						+ ", ent.. " + e.getVisualName()); | 
			
		
	
	
		
			
				
					|  |  |  | @ -629,101 +629,101 @@ public class ScratchMap { | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public void setEntrance(Coord pos) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		enterPoint.setTo(pos); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public void setExit(Coord pos) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		exitPoint.setTo(pos); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public boolean addItem(Item item, Coord pos) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		return addItem(item, pos, true); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public boolean addItem(Item item, Coord pos, boolean canStack) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!isIn(pos)) return false; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		final Tile t = getTile(pos); | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!canStack && t.hasItem()) return false; | 
			
		
	
		
			
				
					|  |  |  |  | 		if (t.dropItem(item)) return true; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		return false; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public boolean addItemInArea(Item item, Coord min, Coord max, int tries) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		final Coord pos = Coord.zero(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		for (int i = 0; i < tries / 2; i++) { | 
			
		
	
		
			
				
					|  |  |  |  | 			pos.x = Calc.randInt(rand, min.x, max.x); | 
			
		
	
		
			
				
					|  |  |  |  | 			pos.y = Calc.randInt(rand, min.y, max.y); | 
			
		
	
		
			
				
					|  |  |  |  | 			if (addItem(item, pos, false)) return true; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		for (int i = 0; i < tries - (tries / 2); i++) { | 
			
		
	
		
			
				
					|  |  |  |  | 			pos.x = Calc.randInt(rand, min.x, max.x); | 
			
		
	
		
			
				
					|  |  |  |  | 			pos.y = Calc.randInt(rand, min.y, max.y); | 
			
		
	
		
			
				
					|  |  |  |  | 			if (addItem(item, pos, true)) return true; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		return false; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public boolean addItemInMap(Item item, int tries) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		return addItemInArea(item, genMin, genMax, tries); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public boolean addEntityInArea(Entity entity, Coord min, Coord max, int tries) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		final Coord pos = Coord.zero(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		for (int i = 0; i < tries; i++) { | 
			
		
	
		
			
				
					|  |  |  |  | 			pos.x = Calc.randInt(rand, min.x, max.x); | 
			
		
	
		
			
				
					|  |  |  |  | 			pos.y = Calc.randInt(rand, min.y, max.y); | 
			
		
	
		
			
				
					|  |  |  |  | 			if (!isIn(pos)) continue; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			 | 
			
		
	
		
			
				
					|  |  |  |  | 			if (addEntity(entity, pos)) return true; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		return false; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public boolean addEntityInMap(Entity entity, int tries) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		return addEntityInArea(entity, genMin, genMax, tries); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |  | 	public boolean addEntity(Entity entity, Coord pos) | 
			
		
	
		
			
				
					|  |  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!isIn(pos)) return false; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		if (pos.dist(enterPoint) < 4) return false; // protected distance.
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		if (pos.dist(enterPoint) < 4) return false; // protected distance.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		final Tile t = getTile(pos); | 
			
		
	
		
			
				
					|  |  |  |  | 		if (!t.isWalkable()) return false; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		if (occupied.contains(pos)) return false; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		occupied.add(pos.copy()); | 
			
		
	
		
			
				
					|  |  |  |  | 		entity.setCoord(pos); | 
			
		
	
		
			
				
					|  |  |  |  | 		entities.add(entity); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |  | 		return true; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
	
		
			
				
					|  |  |  | 
 |