mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-02-10 18:57:39 +07:00
Buffered map-load filter support / Spawn path filter
This commit is contained in:
parent
46b2f4cccb
commit
c2ff5a69ef
@ -421,6 +421,7 @@ filters.empty = [lightgray]No filters! Add one with the button below.
|
||||
filter.distort = Distort
|
||||
filter.noise = Noise
|
||||
filter.enemyspawn = Enemy Spawn Select
|
||||
filter.spawnpath = Path To Spawn
|
||||
filter.corespawn = Core Select
|
||||
filter.median = Median
|
||||
filter.oremedian = Ore Median
|
||||
|
@ -29,7 +29,8 @@ public class MapGenerateDialog extends BaseDialog{
|
||||
private final Prov<GenerateFilter>[] filterTypes = new Prov[]{
|
||||
NoiseFilter::new, ScatterFilter::new, TerrainFilter::new, DistortFilter::new,
|
||||
RiverNoiseFilter::new, OreFilter::new, OreMedianFilter::new, MedianFilter::new,
|
||||
BlendFilter::new, MirrorFilter::new, ClearFilter::new, CoreSpawnFilter::new, EnemySpawnFilter::new
|
||||
BlendFilter::new, MirrorFilter::new, ClearFilter::new, CoreSpawnFilter::new,
|
||||
EnemySpawnFilter::new, SpawnPathFilter::new
|
||||
};
|
||||
private final MapEditor editor;
|
||||
private final boolean applied;
|
||||
@ -121,9 +122,9 @@ public class MapGenerateDialog extends BaseDialog{
|
||||
for(int x = 0; x < editor.width(); x++){
|
||||
for(int y = 0; y < editor.height(); y++){
|
||||
Tile tile = editor.tile(x, y);
|
||||
input.apply(x, y, tile.floor(), tile.block(), tile.overlay());
|
||||
input.apply(x, y, tile.block(), tile.floor(), tile.overlay());
|
||||
filter.apply(input);
|
||||
writeTiles[x][y].set(input.floor, input.block, input.ore, tile.team());
|
||||
writeTiles[x][y].set(input.floor, input.block, input.overlay, tile.team());
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,7 +296,7 @@ public class MapGenerateDialog extends BaseDialog{
|
||||
for(Prov<GenerateFilter> gen : filterTypes){
|
||||
GenerateFilter filter = gen.get();
|
||||
|
||||
if((!applied && filter.isBuffered()) || (filter.isPost() && applied)) continue;
|
||||
if((filter.isPost() && applied)) continue;
|
||||
|
||||
selection.cont.button(filter.name(), () -> {
|
||||
filters.add(filter);
|
||||
@ -369,9 +370,9 @@ public class MapGenerateDialog extends BaseDialog{
|
||||
pixmap.each((px, py) -> {
|
||||
int x = px * scaling, y = py * scaling;
|
||||
GenTile tile = buffer1[px][py];
|
||||
input.apply(x, y, content.block(tile.floor), content.block(tile.block), content.block(tile.ore));
|
||||
input.apply(x, y, content.block(tile.block), content.block(tile.floor), content.block(tile.ore));
|
||||
filter.apply(input);
|
||||
buffer2[px][py].set(input.floor, input.block, input.ore, Team.get(tile.team));
|
||||
buffer2[px][py].set(input.floor, input.block, input.overlay, Team.get(tile.team));
|
||||
});
|
||||
|
||||
pixmap.each((px, py) -> buffer1[px][py].set(buffer2[px][py]));
|
||||
|
@ -26,6 +26,6 @@ public class DistortFilter extends GenerateFilter{
|
||||
|
||||
in.floor = tile.floor();
|
||||
if(!tile.block().synthetic() && !in.block.synthetic()) in.block = tile.block();
|
||||
in.ore = tile.overlay();
|
||||
in.overlay = tile.overlay();
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,10 @@ import arc.math.*;
|
||||
import arc.scene.ui.*;
|
||||
import arc.util.*;
|
||||
import arc.util.noise.*;
|
||||
import mindustry.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
public abstract class GenerateFilter{
|
||||
@ -15,15 +18,42 @@ public abstract class GenerateFilter{
|
||||
|
||||
public void apply(Tiles tiles, GenerateInput in){
|
||||
this.in = in;
|
||||
for(Tile tile : tiles){
|
||||
in.apply(tile.x, tile.y, tile.floor(), tile.block(), tile.overlay());
|
||||
apply();
|
||||
|
||||
tile.setFloor(in.floor.asFloor());
|
||||
tile.setOverlay(!in.floor.asFloor().hasSurface() ? Blocks.air : in.ore);
|
||||
if(isBuffered()){
|
||||
//buffer of tiles used, each tile packed into a long struct
|
||||
long[] buffer = new long[tiles.width * tiles.height];
|
||||
|
||||
if(!tile.block().synthetic() && !in.block.synthetic()){
|
||||
tile.setBlock(in.block);
|
||||
//save to buffer
|
||||
for(int i = 0; i < tiles.width * tiles.height; i++){
|
||||
Tile tile = tiles.geti(i);
|
||||
buffer[i] = TileBuffer.get(tile.blockID(), tile.floorID(), tile.overlayID());
|
||||
}
|
||||
|
||||
for(int i = 0; i < tiles.width * tiles.height; i++){
|
||||
Tile tile = tiles.geti(i);
|
||||
long b = buffer[i];
|
||||
|
||||
in.apply(tile.x, tile.y, Vars.content.block(TileBuffer.block(b)), Vars.content.block(TileBuffer.floor(b)), Vars.content.block(TileBuffer.overlay(b)));
|
||||
apply();
|
||||
|
||||
tile.setFloor(in.floor.asFloor());
|
||||
tile.setOverlay(!in.floor.asFloor().hasSurface() ? Blocks.air : in.overlay);
|
||||
|
||||
if(!tile.block().synthetic() && !in.block.synthetic()){
|
||||
tile.setBlock(in.block);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
for(Tile tile : tiles){
|
||||
in.apply(tile.x, tile.y, tile.block(), tile.floor(), tile.overlay());
|
||||
apply();
|
||||
|
||||
tile.setFloor(in.floor.asFloor());
|
||||
tile.setOverlay(!in.floor.asFloor().hasSurface() ? Blocks.air : in.overlay);
|
||||
|
||||
if(!tile.block().synthetic() && !in.block.synthetic()){
|
||||
tile.setBlock(in.block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -89,16 +119,16 @@ public abstract class GenerateFilter{
|
||||
public int x, y, width, height;
|
||||
|
||||
/** output parameters */
|
||||
public Block floor, block, ore;
|
||||
public Block floor, block, overlay;
|
||||
|
||||
Simplex noise = new Simplex();
|
||||
RidgedPerlin pnoise = new RidgedPerlin(0, 1);
|
||||
TileProvider buffer;
|
||||
|
||||
public void apply(int x, int y, Block floor, Block block, Block ore){
|
||||
public void apply(int x, int y, Block block, Block floor, Block overlay){
|
||||
this.floor = floor;
|
||||
this.block = block;
|
||||
this.ore = ore;
|
||||
this.overlay = overlay;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
@ -119,4 +149,9 @@ public abstract class GenerateFilter{
|
||||
Tile get(int x, int y);
|
||||
}
|
||||
}
|
||||
|
||||
@Struct
|
||||
class TileBufferStruct{
|
||||
short block, floor, overlay;
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class MirrorFilter extends GenerateFilter{
|
||||
if(!tile.block().synthetic()){
|
||||
in.block = tile.block();
|
||||
}
|
||||
in.ore = tile.overlay();
|
||||
in.overlay = tile.overlay();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,8 @@ public class OreFilter extends GenerateFilter{
|
||||
public void apply(){
|
||||
float noise = noise(in.x, in.y, scl, 1f, octaves, falloff);
|
||||
|
||||
if(noise > threshold && in.ore != Blocks.spawn){
|
||||
in.ore = ore;
|
||||
if(noise > threshold && in.overlay != Blocks.spawn){
|
||||
in.overlay = ore;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,14 +29,14 @@ public class OreMedianFilter extends GenerateFilter{
|
||||
|
||||
@Override
|
||||
public void apply(){
|
||||
if(in.ore == Blocks.spawn) return;
|
||||
if(in.overlay == Blocks.spawn) return;
|
||||
|
||||
int cx = (in.x / 2) * 2;
|
||||
int cy = (in.y / 2) * 2;
|
||||
if(in.ore != Blocks.air){
|
||||
if(!(in.tile(cx + 1, cy).overlay() == in.ore && in.tile(cx, cy).overlay() == in.ore && in.tile(cx + 1, cy + 1).overlay() == in.ore && in.tile(cx, cy + 1).overlay() == in.ore &&
|
||||
if(in.overlay != Blocks.air){
|
||||
if(!(in.tile(cx + 1, cy).overlay() == in.overlay && in.tile(cx, cy).overlay() == in.overlay && in.tile(cx + 1, cy + 1).overlay() == in.overlay && in.tile(cx, cy + 1).overlay() == in.overlay &&
|
||||
!in.tile(cx + 1, cy).block().isStatic() && !in.tile(cx, cy).block().isStatic() && !in.tile(cx + 1, cy + 1).block().isStatic() && !in.tile(cx, cy + 1).block().isStatic())){
|
||||
in.ore = Blocks.air;
|
||||
in.overlay = Blocks.air;
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,6 +58,6 @@ public class OreMedianFilter extends GenerateFilter{
|
||||
int index = Math.min((int)(blocks.size * percentile), blocks.size - 1);
|
||||
int overlay = blocks.get(index);
|
||||
|
||||
in.ore = Vars.content.block(overlay);
|
||||
in.overlay = Vars.content.block(overlay);
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class ScatterFilter extends GenerateFilter{
|
||||
if(!block.isOverlay()){
|
||||
in.block = block;
|
||||
}else{
|
||||
in.ore = block;
|
||||
in.overlay = block;
|
||||
}
|
||||
}
|
||||
|
||||
|
64
core/src/mindustry/maps/filters/SpawnPathFilter.java
Normal file
64
core/src/mindustry/maps/filters/SpawnPathFilter.java
Normal file
@ -0,0 +1,64 @@
|
||||
package mindustry.maps.filters;
|
||||
|
||||
import arc.math.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.ai.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.maps.filters.FilterOption.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.storage.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
/** Selects X spawns from the spawn pool.*/
|
||||
public class SpawnPathFilter extends GenerateFilter{
|
||||
int radius = 3;
|
||||
|
||||
@Override
|
||||
public FilterOption[] options(){
|
||||
return Structs.arr(
|
||||
new SliderOption("radius", () -> radius, f -> radius = (int)f, 1, 20).display()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Tiles tiles, GenerateInput in){
|
||||
Tile core = null;
|
||||
var spawns = new Seq<Tile>();
|
||||
|
||||
for(Tile tile : tiles){
|
||||
if(tile.overlay() == Blocks.spawn){
|
||||
spawns.add(tile);
|
||||
}
|
||||
if(tile.block() instanceof CoreBlock && tile.team() != Vars.state.rules.waveTeam){
|
||||
core = tile;
|
||||
}
|
||||
}
|
||||
|
||||
if(core != null && spawns.any()){
|
||||
for(var spawn : spawns){
|
||||
var path = Astar.pathfind(core.x, core.y, spawn.x, spawn.y, t -> t.solid() ? 20 : 1, Astar.manhattan, tile -> !tile.floor().isDeep());
|
||||
for(var tile : path){
|
||||
for(int x = -radius; x <= radius; x++){
|
||||
for(int y = -radius; y <= radius; y++){
|
||||
int wx = tile.x + x, wy = tile.y + y;
|
||||
if(Structs.inBounds(wx, wy, world.width(), world.height()) && Mathf.within(x, y, radius)){
|
||||
Tile other = tiles.getn(wx, wy);
|
||||
if(!other.synthetic()){
|
||||
other.setBlock(Blocks.air);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPost(){
|
||||
return true;
|
||||
}
|
||||
}
|
@ -31,11 +31,10 @@ public class TerrainFilter extends GenerateFilter{
|
||||
float noise = noise(in.x, in.y, scl, magnitude, octaves, falloff) + Mathf.dst((float)in.x / in.width, (float)in.y / in.height, 0.5f, 0.5f) * circleScl;
|
||||
|
||||
in.floor = floor;
|
||||
in.ore = Blocks.air;
|
||||
|
||||
if(noise >= threshold){
|
||||
in.block = block;
|
||||
}else{
|
||||
}else if(!in.block.synthetic()){
|
||||
in.block = Blocks.air;
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ public abstract class BasicGenerator implements WorldGenerator{
|
||||
for(int x = -rad; x <= rad; x++){
|
||||
for(int y = -rad; y <= rad; y++){
|
||||
int wx = cx + x, wy = cy + y;
|
||||
if(Structs.inBounds(wx, wy, width, height) && Mathf.dst(x, y, 0, 0) <= rad){
|
||||
if(Structs.inBounds(wx, wy, width, height) && Mathf.within(x, y, rad)){
|
||||
Tile other = tiles.getn(wx, wy);
|
||||
other.setBlock(Blocks.air);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user