/** * Constructs a GlowBallEffect with explicit settings for some fields. The valid cells this can affect will be * the full expanse of the IPackedColorPanel. * @param targeting the IPackedColorPanel to affect * @param duration the duration of this PanelEffect in seconds, as a float * @param valid the valid cells that can be changed by this PanelEffect, as a GreasedRegion * @param start the starting point for the glow ball(s) * @param end the ending point for the glow ball(s) * @param radius the radius of the explosion, in cells */ public GlowBallEffect(IPackedColorPanel targeting, float duration, GreasedRegion valid, Coord start, Coord end, int radius) { super(targeting, duration, valid); Arrays.fill(centers, start); this.end = end; this.radius = radius; resMap = ArrayTools.fill(1.0, validCells.width, validCells.height); validCells.writeDoublesInto(resMap, 0.0); lightMaps[0] = new double[validCells.width][validCells.height]; FOV.reuseFOV(resMap, lightMaps[0], start.x, start.y, radius + 0.5); validCells.not().writeDoublesInto(lightMaps[0], 0.0); validCells.not(); for (int i = 1; i < 16; i++) { lightMaps[i] = lightMaps[0]; } affected = Radius.inCircle(start.x, start.y, radius, false, validCells.width, validCells.height); }
/** * Constructs an ExplosionEffect with explicit settings for most fields. * @param targeting the IPackedColorPanel to affect * @param duration the duration of this PanelEffect in seconds, as a float * @param valid the valid cells that can be changed by this PanelEffect, as a GreasedRegion * @param center the center of the explosion * @param radius the radius of the explosion, in cells */ public ExplosionEffect(IPackedColorPanel targeting, float duration, GreasedRegion valid, Coord center, int radius) { super(targeting, duration, valid); this.center = center; this.radius = radius; double[][] resMap = ArrayTools.fill(1.0, validCells.width, validCells.height); validCells.writeDoublesInto(resMap, 0.0); lightMap = new double[validCells.width][validCells.height]; FOV.reuseFOV(resMap, lightMap, center.x, center.y, radius + 0.5); validCells.not().writeDoublesInto(lightMap, 0.0); validCells.not(); affected = Radius.inCircle(center.x, center.y, radius, false, validCells.width, validCells.height); }
/** * Constructs an ExplosionEffect with explicit settings for most fields; this constructor allows the case where * an explosion is directed in a cone or sector shape. It will center the sector on {@code angle} (in degrees) * and will cover an amount of the circular area (in degrees) equal to {@code span}. * @param targeting the IPackedColorPanel to affect * @param duration the duration of this PanelEffect in seconds, as a float * @param valid the valid cells that can be changed by this PanelEffect, as a GreasedRegion * @param center the center of the explosion * @param radius the radius of the explosion, in cells * @param angle the angle, in degrees, that will be the center of the sector-shaped effect * @param span the span, in degrees, of the full arc at the end of the sector-shaped effect */ public ExplosionEffect(IPackedColorPanel targeting, float duration, GreasedRegion valid, Coord center, int radius, double angle, double span) { super(targeting, duration, valid); this.center = center; this.radius = radius; double[][] resMap = ArrayTools.fill(1.0, validCells.width, validCells.height); validCells.writeDoublesInto(resMap, 0.0); lightMap = new double[validCells.width][validCells.height]; FOV.reuseFOV(resMap, lightMap, center.x, center.y, radius + 0.5, Radius.CIRCLE, angle, span); validCells.not().writeDoublesInto(lightMap, 0.0); validCells.not(); affected = Radius.inCircle(center.x, center.y, radius, false, validCells.width, validCells.height); }
/** * Discouraged from active use; slower than {@link squidpony.squidai.DijkstraMap} and has less features. * @param map a 2D char array where '#' is a wall * @param goals an array or vararg of Coord to get the distances toward * @return a 2D double array of distances from a cell to the nearest goal */ public static double[][] dijkstraScan8way(char[][] map, Coord... goals) { if(map == null || map.length <= 0 || map[0].length <= 0 || goals == null || goals.length <= 0) return new double[0][0]; int w = map.length, h = map[0].length, ys = (h + 63) >>> 6; double[][] numbers = new double[w][h]; GreasedRegion walls = new GreasedRegion(map, '#'), floors = new GreasedRegion(walls).not(), middle = new GreasedRegion(w, h, goals).and(floors); ArrayList<GreasedRegion> regions = middle.floodSeriesToLimit8way(floors); int l = regions.size(); for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { for (int i = 0; i < l; i++) { numbers[x][y] += (regions.get(i).data[x * ys + (y >> 6)] & (1L << (y & 63))) != 0 ? 1 : 0; } } } return numbers; }
/** * Discouraged from active use; slower than {@link squidpony.squidai.DijkstraMap} and has less features. * @param map a 2D char array where '#' is a wall * @param goals an array or vararg of Coord to get the distances toward * @return a 2D double array of distances from a cell to the nearest goal */ public static double[][] dijkstraScan(char[][] map, Coord... goals) { if(map == null || map.length <= 0 || map[0].length <= 0 || goals == null || goals.length <= 0) return new double[0][0]; int w = map.length, h = map[0].length, ys = (h + 63) >>> 6; double[][] numbers = new double[w][h]; GreasedRegion walls = new GreasedRegion(map, '#'), floors = new GreasedRegion(walls).not(), middle = new GreasedRegion(w, h, goals).and(floors); ArrayList<GreasedRegion> regions = middle.floodSeriesToLimit(floors); int l = regions.size(); for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { for (int i = 0; i < l; i++) { numbers[x][y] += (regions.get(i).data[x * ys + (y >> 6)] & (1L << (y & 63))) != 0 ? 1 : 0; } } } return numbers; } /**
/** * Constructs a concrete WorldMapGenerator for a map that should have land in roughly the same places as the * given GreasedRegion's "on" cells, using an elliptical projection (specifically, a Mollweide projection). * Takes an initial seed, the GreasedRegion containing land positions, parameters for noise generation (a * {@link Noise3D} implementation, which is usually {@link FastNoise#instance}, and a multiplier on how many * octaves of noise to use, with 1.0 being normal (high) detail and higher multipliers producing even more * detailed noise when zoomed-in). The {@code initialSeed} parameter may or may not be used, * since you can specify the seed to use when you call {@link #generate(long)}. The width and height of the map * cannot be changed after the fact. FastNoise will be the fastest 3D generator to use for * {@code noiseGenerator}, and the seed it's constructed with doesn't matter because this will change the * seed several times at different scales of noise (it's fine to use the static {@link FastNoise#instance} * because it has no changing state between runs of the program). The {@code octaveMultiplier} parameter should * probably be no lower than 0.5, but can be arbitrarily high if you're willing to spend much more time on * generating detail only noticeable at very high zoom; normally 1.0 is fine and may even be too high for maps * that don't require zooming. * @param initialSeed the seed for the GWTRNG this uses; this may also be set per-call to generate * @param toMimic the world map to imitate, as a GreasedRegion with land as "on"; the height and width will be copied * @param noiseGenerator an instance of a noise generator capable of 3D noise, usually {@link FastNoise} or {@link FastNoise} * @param octaveMultiplier used to adjust the level of detail, with 0.5 at the bare-minimum detail and 1.0 normal */ public MimicMap(long initialSeed, GreasedRegion toMimic, Noise3D noiseGenerator, double octaveMultiplier) { super(initialSeed, toMimic.width, toMimic.height, noiseGenerator, octaveMultiplier); earth = toMimic; earthOriginal = earth.copy(); coast = earth.copy().not().fringe(2); shallow = earth.copy().fringe(2); }
/** * Constructs a concrete WorldMapGenerator for a map that should have land in roughly the same places as the * given GreasedRegion's "on" cells, using an elliptical projection (specifically, a Mollweide projection). * Takes an initial seed, the GreasedRegion containing land positions, parameters for noise generation (a * {@link Noise3D} implementation, which is usually {@link FastNoise#instance}, and a multiplier on how many * octaves of noise to use, with 1.0 being normal (high) detail and higher multipliers producing even more * detailed noise when zoomed-in). The {@code initialSeed} parameter may or may not be used, * since you can specify the seed to use when you call {@link #generate(long)}. The width and height of the map * cannot be changed after the fact. FastNoise will be the fastest 3D generator to use for * {@code noiseGenerator}, and the seed it's constructed with doesn't matter because this will change the * seed several times at different scales of noise (it's fine to use the static {@link FastNoise#instance} * because it has no changing state between runs of the program). The {@code octaveMultiplier} parameter should * probably be no lower than 0.5, but can be arbitrarily high if you're willing to spend much more time on * generating detail only noticeable at very high zoom; normally 1.0 is fine and may even be too high for maps * that don't require zooming. * @param initialSeed the seed for the GWTRNG this uses; this may also be set per-call to generate * @param toMimic the world map to imitate, as a GreasedRegion with land as "on"; the height and width will be copied * @param noiseGenerator an instance of a noise generator capable of 3D noise, usually {@link FastNoise} or {@link FastNoise} * @param octaveMultiplier used to adjust the level of detail, with 0.5 at the bare-minimum detail and 1.0 normal */ public LocalMimicMap(long initialSeed, GreasedRegion toMimic, Noise2D noiseGenerator, double octaveMultiplier) { super(initialSeed, toMimic.width, toMimic.height, noiseGenerator, octaveMultiplier); earth = toMimic; earthOriginal = earth.copy(); coast = earth.copy().not().fringe(2); shallow = earth.copy().fringe(2); }
workingBody.remake(potentialBody).or(potentialSolid).andNot(alwaysSolid).and(randomRegion); workingSolid.andNot(workingBody).or(randomRegion.remake(workingBody).fringe8way()); workingShade.remake(workingBody).neighborDown().not().and(workingBody); workingShine.remake(workingBody).neighborUp().not().and(workingBody).andNot(workingShade); workingBody.andNot(workingShade).andNot(workingShine); for (int x = 0, o = w*2-1; x < w; x++, o--) {
workingBody.remake(potentialBody).or(potentialSolid).andNot(alwaysSolid).and(randomRegion); workingSolid.andNot(workingBody).or(randomRegion.remake(workingBody).fringe()); workingShade.remake(workingBody).neighborDown().not().and(workingBody); workingShine.remake(workingBody).neighborUp().not().and(workingBody).andNot(workingShade); workingBody.andNot(workingShade).andNot(workingShine); for (int x = 0, o = w*2-1; x < w; x++, o--) {
sty = Math.min(Math.max((wmg.zoomStartY - (height >> 1)) / ((2 << wmg.zoom) - 2), 0), height); GreasedRegion nation = new GreasedRegion(wmg.landData); GreasedRegion fillable = new GreasedRegion(politicalMap, '~').not(); for (int i = 0; i < wmg.zoom; i++) { fillable.zoom(stx, sty);
GreasedRegion bounds = new GreasedRegion(width, height).not().retract(5), smallerBounds = bounds.copy().retract(5), area = new GreasedRegion(width, height), tmpEdge = new GreasedRegion(width, height), tmpInner = new GreasedRegion(width, height), entries.put(tmpInner.singleRandom(rng), (rng.nextDouble() + 1.5) * 0.4); tmpOOB.remake(area).not(); m2.not().writeIntsInto(heightMap, -1);