Better generation

This commit is contained in:
Anuken
2020-06-05 13:42:48 -04:00
parent cf02a75846
commit b3ff616af2
4 changed files with 78 additions and 55 deletions

Binary file not shown.

View File

@@ -72,7 +72,11 @@ public class BaseRegistry{
part.tier = schem.tiles.sumf(s -> s.block.buildCost / s.block.buildCostMultiplier); part.tier = schem.tiles.sumf(s -> s.block.buildCost / s.block.buildCostMultiplier);
(part.core != null ? cores : parts).add(part); if(part.core != null){
cores.add(part);
}else if(part.requiredItem == null){
parts.add(part);
}
if(drills > 0){ if(drills > 0){
Tmp.v1.scl(1f / drills).scl(1f / tilesize); Tmp.v1.scl(1f / drills).scl(1f / tilesize);

View File

@@ -1,5 +1,6 @@
package mindustry.maps.generators; package mindustry.maps.generators;
import arc.func.*;
import arc.math.*; import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.struct.*; import arc.struct.*;
@@ -23,13 +24,17 @@ public class BaseGenerator{
private static final Schematic tmpSchem2 = new Schematic(new Array<>(), new StringMap(), 0, 0); private static final Schematic tmpSchem2 = new Schematic(new Array<>(), new StringMap(), 0, 0);
private static final Vec2 axis = new Vec2(), rotator = new Vec2(); private static final Vec2 axis = new Vec2(), rotator = new Vec2();
private final static int range = 200;
private Tiles tiles; private Tiles tiles;
private Team team; private Team team;
private ObjectMap<Item, OreBlock> ores = new ObjectMap<>(); private ObjectMap<Item, OreBlock> ores = new ObjectMap<>();
private Array<Tile> cores;
public void generate(Tiles tiles, Array<Tile> cores, Tile spawn, Team team, Sector sector){ public void generate(Tiles tiles, Array<Tile> cores, Tile spawn, Team team, Sector sector){
this.tiles = tiles; this.tiles = tiles;
this.team = team; this.team = team;
this.cores = cores;
for(Block block : content.blocks()){ for(Block block : content.blocks()){
if(block instanceof OreBlock && block.asFloor().itemDrop != null){ if(block instanceof OreBlock && block.asFloor().itemDrop != null){
@@ -41,8 +46,9 @@ public class BaseGenerator{
Array<Block> wallsLarge = content.blocks().select(b -> b instanceof Wall && b.size == 2); Array<Block> wallsLarge = content.blocks().select(b -> b instanceof Wall && b.size == 2);
float bracket = 0.1f; float bracket = 0.1f;
int range = 200;
int wallAngle = 70; //180 for full coverage int wallAngle = 70; //180 for full coverage
double resourceChance = 0.4;
double nonResourceChance = 0.0007;
BasePart coreschem = bases.cores.getFrac(bracket); BasePart coreschem = bases.cores.getFrac(bracket);
Block wall = wallsSmall.getFrac(bracket), wallLarge = wallsLarge.getFrac(bracket); Block wall = wallsSmall.getFrac(bracket), wallLarge = wallsLarge.getFrac(bracket);
@@ -60,71 +66,73 @@ public class BaseGenerator{
} }
} }
//first pass: random schematics //first pass: random item specific schematics
for(Tile core : cores){ pass(tile -> {
core.circle(range, (x, y) -> { if(tile.overlay().itemDrop != null && Mathf.chance(resourceChance)){
Tile tile = tiles.getn(x, y); Array<BasePart> parts = bases.forItem(tile.overlay().itemDrop);
if(tile.overlay().itemDrop != null){ if(!parts.isEmpty()){
Array<BasePart> parts = bases.forItem(tile.overlay().itemDrop); tryPlace(parts.random(), tile.x, tile.y);
if(!parts.isEmpty()){ }
tryPlace(parts.random(), x, y); }else if(tile.overlay().itemDrop == null && Mathf.chance(nonResourceChance)){
tryPlace(bases.parts.random(), tile.x, tile.y);
}
});
if(wallAngle > 0){
//small walls
pass(tile -> {
if(tile.block().alwaysReplace){
boolean any = false;
for(Point2 p : Geometry.d8){
if(Angles.angleDist(Angles.angle(p.x, p.y), spawn.angleTo(tile.x, tile.y)) > wallAngle){
continue;
}
Tile o = tiles.get(tile.x + p.x, tile.y + p.y);
if(o != null && o.team() == team && !(o.block() instanceof Wall)){
any = true;
break;
}
}
if(any){
tile.setBlock(wall, team);
} }
} }
}); });
}
if(wallAngle > 0){ //large walls
//second pass: small walls pass(curr -> {
for(Tile core : cores){ int walls = 0;
core.circle(range, (x, y) -> { for(int cx = 0; cx < 2; cx++){
Tile tile = tiles.getn(x, y); for(int cy = 0; cy < 2; cy++){
if(tile.block().alwaysReplace){ Tile tile = tiles.get(curr.x + cx, curr.y + cy);
boolean any = false; if(tile == null || tile.block().size != 1 || (tile.block() != wall && !tile.block().alwaysReplace)) return;
for(Point2 p : Geometry.d8){ if(tile.block() == wall){
if(Angles.angleDist(Angles.angle(p.x, p.y), spawn.angleTo(core)) > wallAngle){ walls ++;
continue;
}
Tile o = tiles.get(tile.x + p.x, tile.y + p.y);
if(o != null && o.team() == team && !(o.block() instanceof Wall)){
any = true;
break;
}
}
if(any){
tile.setBlock(wall, team);
} }
} }
}); }
}
//third pass: large walls if(walls >= 3){
for(Tile core : cores){ curr.setBlock(wallLarge, team);
core.circle(range, (x, y) -> { }
int walls = 0; });
for(int cx = 0; cx < 2; cx++){
for(int cy = 0; cy < 2; cy++){
Tile tile = tiles.get(x + cx, y + cy);
if(tile == null || tile.block().size != 1 || (tile.block() != wall && !tile.block().alwaysReplace)) return;
if(tile.block() == wall){
walls ++;
}
}
}
if(walls >= 3){
tiles.getn(x, y).setBlock(wallLarge, team);
}
});
}
} }
} }
void pass(Cons<Tile> cons){
Tile core = cores.first();
//for(Tile core : cores){
core.circle(range, (x, y) -> cons.get(tiles.getn(x, y)));
//}
}
boolean tryPlace(BasePart part, int x, int y){ boolean tryPlace(BasePart part, int x, int y){
int rotation = 0; int rotation = Mathf.range(2);
axis.set((int)(part.schematic.width / 2f), (int)(part.schematic.height / 2f)); axis.set((int)(part.schematic.width / 2f), (int)(part.schematic.height / 2f));
Schematic result = rotate(part.schematic, rotation); Schematic result = rotate(part.schematic, rotation);
@@ -151,6 +159,9 @@ public class BaseGenerator{
if(tile.block instanceof Drill){ if(tile.block instanceof Drill){
tile.block.iterateTaken(tile.x + cx, tile.y + cy, (ex, ey) -> { tile.block.iterateTaken(tile.x + cx, tile.y + cy, (ex, ey) -> {
tiles.getn(ex, ey).setOverlay(ores.get(part.requiredItem)); tiles.getn(ex, ey).setOverlay(ores.get(part.requiredItem));
//random ores nearby to make it look more natural
tiles.getc(ex + Mathf.range(1), ey + Mathf.range(1)).setOverlay(ores.get(part.requiredItem));
}); });
} }
} }

View File

@@ -1,6 +1,7 @@
package mindustry.world; package mindustry.world;
import arc.func.*; import arc.func.*;
import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.util.ArcAnnotate.*; import arc.util.ArcAnnotate.*;
@@ -54,6 +55,13 @@ public class Tiles implements Iterable<Tile>{
return array[y*width + x]; return array[y*width + x];
} }
/** @return a tile at coordinates, clamped. */
public @NonNull Tile getc(int x, int y){
x = Mathf.clamp(x, 0, width - 1);
y = Mathf.clamp(y, 0, height - 1);
return array[y*width + x];
}
/** @return a tile at an iteration index [0, width * height] */ /** @return a tile at an iteration index [0, width * height] */
public @NonNull Tile geti(int idx){ public @NonNull Tile geti(int idx){
return array[idx]; return array[idx];