package Roguelike.DungeonGeneration.RoomGenerators;
import java.util.Random;
import Roguelike.DungeonGeneration.DungeonFileParser;
import Roguelike.DungeonGeneration.Symbol;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.XmlReader.Element;
public class Starburst extends AbstractRoomGenerator
{
/*
* Accept values for y and x (considered as the endpoints of lines) between
* 0 and 40, and return an angle in degrees (divided by two). -LM-
*
* This table's input and output need some processing:
*
* Because this table gives degrees for a whole circle, up to radius 20, its
* origin is at (x,y) = (20, 20). Therefore, the input code needs to find
* the origin grid (where the lines being compared come from), and then map
* it to table grid 20,20. Do not, however, actually try to compare the
* angle of a line that begins and ends at the origin with any other line -
* it is impossible mathematically, and the table will return the value "255".
*
* The output of this table also needs to be massaged, in order to avoid the
* discontinuity at 0/180 degrees. This can be done by:
* rotate = 90 - first value
* this rotates the first input to the 90 degree line)
* tmp = ABS(second value + rotate) % 180
* diff = ABS(90 - tmp) = the angular difference (divided by two) between
* the first and second values.
*
* Note that grids diagonal to the origin have unique angles.
*/
private static final int[][] get_angle_to_grid =
{
{ 68, 67, 66, 65, 64, 63, 62, 62, 60, 59, 58, 57, 56, 55, 53, 52, 51, 49, 48, 46, 45, 44, 42, 41, 39, 38, 37, 35, 34, 33, 32, 31, 30, 28, 28, 27, 26, 25, 24, 24, 23 },
{ 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 56, 55, 54, 52, 51, 49, 48, 47, 45, 43, 42, 41, 39, 38, 36, 35, 34, 32, 31, 30, 29, 28, 27, 26, 25, 24, 24, 23, 22 },
{ 69, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 58, 57, 56, 54, 53, 51, 50, 48, 47, 45, 43, 42, 40, 39, 37, 36, 34, 33, 32, 30, 29, 28, 27, 26, 25, 24, 24, 23, 22, 21 },
{ 70, 69, 69, 68, 67, 66, 65, 64, 63, 61, 60, 59, 58, 56, 55, 53, 52, 50, 48, 47, 45, 43, 42, 40, 38, 37, 35, 34, 32, 31, 30, 29, 27, 26, 25, 24, 24, 23, 22, 21, 20 },
{ 71, 70, 69, 69, 68, 67, 66, 65, 63, 62, 61, 60, 58, 57, 55, 54, 52, 50, 49, 47, 45, 43, 41, 40, 38, 36, 35, 33, 32, 30, 29, 28, 27, 25, 24, 24, 23, 22, 21, 20, 19 },
{ 72, 71, 70, 69, 69, 68, 67, 65, 64, 63, 62, 60, 59, 58, 56, 54, 52, 51, 49, 47, 45, 43, 41, 39, 38, 36, 34, 32, 31, 30, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18 },
{ 73, 72, 71, 70, 69, 69, 68, 66, 65, 64, 63, 61, 60, 58, 57, 55, 53, 51, 49, 47, 45, 43, 41, 39, 37, 35, 33, 32, 30, 29, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17 },
{ 73, 73, 72, 71, 70, 70, 69, 68, 66, 65, 64, 62, 61, 59, 57, 56, 54, 51, 49, 47, 45, 43, 41, 39, 36, 34, 33, 31, 29, 28, 26, 25, 24, 23, 21, 20, 20, 19, 18, 17, 17 },
{ 75, 74, 73, 72, 72, 71, 70, 69, 68, 66, 65, 63, 62, 60, 58, 56, 54, 52, 50, 47, 45, 43, 40, 38, 36, 34, 32, 30, 28, 27, 25, 24, 23, 21, 20, 19, 18, 18, 17, 16, 15 },
{ 76, 75, 74, 74, 73, 72, 71, 70, 69, 68, 66, 65, 63, 61, 59, 57, 55, 53, 50, 48, 45, 42, 40, 37, 35, 33, 31, 29, 27, 25, 24, 23, 21, 20, 19, 18, 17, 16, 16, 15, 14 },
{ 77, 76, 75, 75, 74, 73, 72, 71, 70, 69, 68, 66, 64, 62, 60, 58, 56, 53, 51, 48, 45, 42, 39, 37, 34, 32, 30, 28, 26, 24, 23, 21, 20, 19, 18, 17, 16, 15, 15, 14, 13 },
{ 78, 77, 77, 76, 75, 75, 74, 73, 72, 70, 69, 68, 66, 64, 62, 60, 57, 54, 51, 48, 45, 42, 39, 36, 33, 30, 28, 26, 24, 23, 21, 20, 18, 17, 16, 15, 15, 14, 13, 13, 12 },
{ 79, 79, 78, 77, 77, 76, 75, 74, 73, 72, 71, 69, 68, 66, 63, 61, 58, 55, 52, 49, 45, 41, 38, 35, 32, 29, 27, 24, 23, 21, 19, 18, 17, 16, 15, 14, 13, 13, 12, 11, 11 },
{ 80, 80, 79, 79, 78, 77, 77, 76, 75, 74, 73, 71, 69, 68, 65, 63, 60, 57, 53, 49, 45, 41, 37, 33, 30, 27, 25, 23, 21, 19, 17, 16, 15, 14, 13, 13, 12, 11, 11, 10, 10 },
{ 82, 81, 81, 80, 80, 79, 78, 78, 77, 76, 75, 73, 72, 70, 68, 65, 62, 58, 54, 50, 45, 40, 36, 32, 28, 25, 23, 20, 18, 17, 15, 14, 13, 12, 12, 11, 10, 10, 9, 9, 8 },
{ 83, 83, 82, 82, 81, 81, 80, 79, 79, 78, 77, 75, 74, 72, 70, 68, 64, 60, 56, 51, 45, 39, 34, 30, 26, 23, 20, 18, 16, 15, 13, 12, 11, 11, 10, 9, 9, 8, 8, 7, 7 },
{ 84, 84, 84, 83, 83, 83, 82, 81, 81, 80, 79, 78, 77, 75, 73, 71, 68, 63, 58, 52, 45, 38, 32, 27, 23, 19, 17, 15, 13, 12, 11, 10, 9, 9, 8, 7, 7, 7, 6, 6, 6 },
{ 86, 86, 85, 85, 85, 84, 84, 84, 83, 82, 82, 81, 80, 78, 77, 75, 72, 68, 62, 54, 45, 36, 28, 23, 18, 15, 13, 12, 10, 9, 8, 8, 7, 6, 6, 6, 5, 5, 5, 4, 4 },
{ 87, 87, 87, 87, 86, 86, 86, 86, 85, 85, 84, 84, 83, 82, 81, 79, 77, 73, 68, 58, 45, 32, 23, 17, 13, 11, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3 },
{ 89, 88, 88, 88, 88, 88, 88, 88, 88, 87, 87, 87, 86, 86, 85, 84, 83, 81, 77, 68, 45, 23, 13, 9, 7, 6, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
{ 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 91, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 94, 94, 95, 96, 97, 99, 103, 113, 135, 158, 167, 171, 173, 174, 175, 176, 176, 177, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, 179 },
{ 93, 93, 93, 93, 94, 94, 94, 94, 95, 95, 96, 96, 97, 98, 99, 101, 103, 107, 113, 122, 135, 148, 158, 163, 167, 169, 171, 172, 173, 174, 174, 175, 175, 176, 176, 176, 176, 177, 177, 177, 177 },
{ 94, 94, 95, 95, 95, 96, 96, 96, 97, 98, 98, 99, 100, 102, 103, 105, 108, 113, 118, 126, 135, 144, 152, 158, 162, 165, 167, 168, 170, 171, 172, 172, 173, 174, 174, 174, 175, 175, 175, 176, 176 },
{ 96, 96, 96, 97, 97, 97, 98, 99, 99, 100, 101, 102, 103, 105, 107, 109, 113, 117, 122, 128, 135, 142, 148, 153, 158, 161, 163, 165, 167, 168, 169, 170, 171, 171, 172, 173, 173, 173, 174, 174, 174 },
{ 97, 97, 98, 98, 99, 99, 100, 101, 101, 102, 103, 105, 106, 108, 110, 113, 116, 120, 124, 129, 135, 141, 146, 150, 154, 158, 160, 162, 164, 165, 167, 168, 169, 169, 170, 171, 171, 172, 172, 173, 173 },
{ 98, 99, 99, 100, 100, 101, 102, 102, 103, 104, 105, 107, 108, 110, 113, 115, 118, 122, 126, 130, 135, 140, 144, 148, 152, 155, 158, 160, 162, 163, 165, 166, 167, 168, 168, 169, 170, 170, 171, 171, 172 },
{ 100, 100, 101, 101, 102, 103, 103, 104, 105, 106, 107, 109, 111, 113, 115, 117, 120, 123, 127, 131, 135, 139, 143, 147, 150, 153, 155, 158, 159, 161, 163, 164, 165, 166, 167, 167, 168, 169, 169, 170, 170 },
{ 101, 101, 102, 103, 103, 104, 105, 106, 107, 108, 109, 111, 113, 114, 117, 119, 122, 125, 128, 131, 135, 139, 142, 145, 148, 151, 153, 156, 158, 159, 161, 162, 163, 164, 165, 166, 167, 167, 168, 169, 169 },
{ 102, 103, 103, 104, 105, 105, 106, 107, 108, 110, 111, 113, 114, 116, 118, 120, 123, 126, 129, 132, 135, 138, 141, 144, 147, 150, 152, 154, 156, 158, 159, 160, 162, 163, 164, 165, 165, 166, 167, 167, 168 },
{ 103, 104, 105, 105, 106, 107, 108, 109, 110, 111, 113, 114, 116, 118, 120, 122, 124, 127, 129, 132, 135, 138, 141, 143, 146, 148, 150, 152, 154, 156, 158, 159, 160, 161, 162, 163, 164, 165, 165, 166, 167 },
{ 104, 105, 106, 106, 107, 108, 109, 110, 111, 113, 114, 115, 117, 119, 121, 123, 125, 127, 130, 132, 135, 138, 140, 143, 145, 147, 149, 151, 153, 155, 156, 158, 159, 160, 161, 162, 163, 164, 164, 165, 166 },
{ 105, 106, 107, 108, 108, 109, 110, 111, 113, 114, 115, 117, 118, 120, 122, 124, 126, 128, 130, 133, 135, 137, 140, 142, 144, 146, 148, 150, 152, 153, 155, 156, 158, 159, 160, 161, 162, 162, 163, 164, 165 },
{ 107, 107, 108, 109, 110, 110, 111, 113, 114, 115, 116, 118, 119, 121, 123, 124, 126, 129, 131, 133, 135, 137, 139, 141, 144, 146, 147, 149, 151, 152, 154, 155, 156, 158, 159, 160, 160, 161, 162, 163, 163 },
{ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 119, 120, 122, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 148, 150, 151, 153, 154, 155, 156, 158, 159, 159, 160, 161, 162, 163 },
{ 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 120, 121, 122, 124, 126, 128, 129, 131, 133, 135, 137, 139, 141, 142, 144, 146, 148, 149, 150, 152, 153, 154, 155, 157, 158, 159, 159, 160, 161, 162 },
{ 109, 110, 111, 112, 113, 114, 114, 115, 117, 118, 119, 120, 122, 123, 125, 126, 128, 130, 131, 133, 135, 137, 139, 140, 142, 144, 145, 147, 148, 150, 151, 152, 153, 155, 156, 157, 158, 159, 159, 160, 161 },
{ 110, 111, 112, 113, 114, 114, 115, 116, 117, 119, 120, 121, 122, 124, 125, 127, 128, 130, 132, 133, 135, 137, 138, 140, 142, 143, 145, 146, 148, 149, 150, 151, 153, 154, 155, 156, 157, 158, 159, 159, 160 },
{ 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 122, 123, 124, 126, 127, 129, 130, 132, 133, 135, 137, 138, 140, 141, 143, 144, 146, 147, 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 159 },
{ 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 124, 125, 126, 128, 129, 131, 132, 133, 135, 137, 138, 139, 141, 142, 144, 145, 146, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159 },
{ 113, 114, 114, 115, 116, 117, 118, 118, 120, 121, 122, 123, 124, 125, 127, 128, 129, 131, 132, 134, 135, 136, 138, 139, 141, 142, 143, 145, 146, 147, 148, 149, 150, 152, 152, 153, 154, 155, 156, 157, 158 }
};
/*
* Mark a starburst shape in the dungeon with the CAVE_TEMP flag, given the
* coordinates of a section of the dungeon in "box" format. -LM-, -DG-
*
* Starburst are made in three steps:
* 1: Choose a box size-dependant number of arcs. Large starburts need to
* look less granular and alter their shape more often, so they need
* more arcs.
* 2: For each of the arcs, calculate the portion of the full circle it
* includes, and its maximum effect range (how far in that direction
* we can change features in). This depends on starburst size, shape, and
* the maximum effect range of the previous arc.
* 3: Use the table "get_angle_to_grid" to supply angles to each grid in
* the room. If the distance to that grid is not greater than the
* maximum effect range that applies at that angle, change the feature
* if appropriate (this depends on feature type).
*
* Usage notes:
* - This function uses a table that cannot handle distances larger than
* 20, so it calculates a distance conversion factor for larger starbursts.
* - This function is not good at handling starbursts much longer along one axis
* than the other.
* This function doesn't mark any grid in the perimeter of the given box.
*
*/
public void process(Symbol[][] grid, Symbol floor, Symbol wall, Random ran, DungeonFileParser dfp)
{
int y0, x0, y, x, ny, nx;
int i;
int size;
int dist, max_dist, dist_conv, dist_check;
int height, width, arc_dist;
int degree_first, center_of_arc, degree;
/* Special variant starburst. Discovered by accident. */
boolean make_cloverleaf = false;
/* Holds first degree of arc, maximum effect distance in arc. */
int[][] arc = new int[45][2];
/* Number (max 45) of arcs. */
int arc_num;
/* Get room height and width. */
height = grid[0].length;
width = grid.length;
// reset to all wall
for (x = 0; x < width; x++)
{
for (y = 0; y < height; y++)
{
grid[x][y] = wall;
}
}
/* Note the "size" */
size = 2 + (width + height) / 22;
/* Get a shrinkage ratio for large starbursts, as table is limited. */
if ((width > 40) || (height > 40))
{
if (width > height) dist_conv = 1 + (10 * width / 40);
else dist_conv = 1 + (10 * height / 40);
}
else dist_conv = 10;
/* Make a cloverleaf starburst sometimes. (discovered by accident) */
if (height > 10 && ran.nextInt(20) == 0)
{
arc_num = 12;
make_cloverleaf = true;
}
/* Usually, we make a normal starburst. */
else
{
/* Ask for a reasonable number of arcs. */
arc_num = 8 + (height * width / 80);
arc_num = (arc_num - 3) + ran.nextInt(6);;
if (arc_num < 8) arc_num = 8;
if (arc_num > 45) arc_num = 45;
}
/* Get the center of the starburst. */
y0 = height / 2;
x0 = width / 2;
/* Start out at zero degrees. */
degree_first = 0;
/* Determine the start degrees and expansion distance for each arc. */
for (i = 0; i < arc_num; i++)
{
/* Get the first degree for this arc (using 180-degree circles). */
arc[i][0] = degree_first;
/* Get a slightly randomized start degree for the next arc. */
degree_first += 180 / arc_num;
/* Do not entirely leave the usual range */
if (degree_first < 180 * (i+1) / arc_num)
{
degree_first = 180 * (i+1) / arc_num;
}
if (degree_first > (180 + arc_num) * (i+1) / arc_num)
{
degree_first = (180 + arc_num) * (i+1) / arc_num;
}
/* Get the center of the arc (convert from 180 to 360 circle). */
center_of_arc = degree_first + arc[i][0];
/* Get arc distance from the horizontal (0 and 180 degrees) */
if (center_of_arc <= 90) arc_dist = center_of_arc;
else if (center_of_arc >= 270) arc_dist = Math.abs(center_of_arc - 360);
else arc_dist = Math.abs(center_of_arc - 180);
/* Special case -- Handle cloverleafs */
if ((arc_dist == 45) && (make_cloverleaf)) dist = 0;
/*
* Usual case -- Calculate distance to expand outwards. Pay more
* attention to width near the horizontal, more attention to height
* near the vertical.
*/
else dist = ((height * arc_dist) + (width * (90 - arc_dist))) / 90;
/* Randomize distance (should never be greater than radius) */
arc[i][1] = dist >= 4 ? ran.nextInt(dist/4)+(dist/4) : dist;
/* Keep variability under control (except in special cases). */
if ((dist != 0) && (i != 0))
{
int diff = arc[i][1] - arc[i-1][1];
if (Math.abs(diff) > size)
{
if (diff > 0) arc[i][1] = arc[i-1][1] + size;
else arc[i][1] = arc[i-1][1] - size;
}
}
}
/* Neaten up final arc of circle by comparing it to the first. */
{
int diff = arc[arc_num - 1][1] - arc[0][1];
if (Math.abs(diff) > size)
{
if (diff > 0) arc[arc_num - 1][1] = arc[0][1] + size;
else arc[arc_num - 1][1] = arc[0][1] - size;
}
}
/* Precalculate check distance. */
dist_check = 21 * dist_conv / 10;
/* Change grids between (and not including) the edges. */
for (y = 1; y < height; y++)
{
for (x = 1; x < width; x++)
{
/* Get distance to grid. */
dist = (int)Vector2.dst(y0, x0, y, x);
/* Look at the grid if within check distance. */
if (dist < dist_check)
{
/* Convert and reorient grid for table access. */
ny = 20 + 10 * (y - y0) / dist_conv;
nx = 20 + 10 * (x - x0) / dist_conv;
/* Illegal table access is bad. */
if ((ny < 0) || (ny > 40) || (nx < 0) || (nx > 40)) continue;
/* Get angle to current grid. */
degree = get_angle_to_grid[ny][nx];
/* Scan arcs to find the one that applies here. */
for (i = arc_num - 1; i >= 0; i--)
{
if (arc[i][0] <= degree)
{
max_dist = arc[i][1];
/* Must be within effect range. */
if (max_dist >= dist)
{
/* Mark the grid */
grid[x][y] = floor;
}
/* Arc found. End search */
break;
}
}
}
}
}
}
@Override
public void parse(Element xml)
{
}
}