Awful enemy base generation
This commit is contained in:
+1
-5
@@ -10,6 +10,7 @@ logs/
|
|||||||
/desktop/mindustry-saves/
|
/desktop/mindustry-saves/
|
||||||
/desktop/mindustry-maps/
|
/desktop/mindustry-maps/
|
||||||
/desktop/gifexport/
|
/desktop/gifexport/
|
||||||
|
/gifs/
|
||||||
/core/lib/
|
/core/lib/
|
||||||
/ios/assets/
|
/ios/assets/
|
||||||
/core/assets-raw/sprites/generated/
|
/core/assets-raw/sprites/generated/
|
||||||
@@ -28,7 +29,6 @@ core/assets/saves/
|
|||||||
/core/assets/saves/
|
/core/assets/saves/
|
||||||
steam_appid.txt
|
steam_appid.txt
|
||||||
/test_files/
|
/test_files/
|
||||||
/annotations/build/
|
|
||||||
/android/assets/mindustry-maps/
|
/android/assets/mindustry-maps/
|
||||||
/android/assets/mindustry-saves/
|
/android/assets/mindustry-saves/
|
||||||
/core/assets/gifexport/
|
/core/assets/gifexport/
|
||||||
@@ -40,11 +40,7 @@ steam_appid.txt
|
|||||||
ios/robovm.properties
|
ios/robovm.properties
|
||||||
packr-out/
|
packr-out/
|
||||||
config/
|
config/
|
||||||
changelog
|
|
||||||
*.gif
|
*.gif
|
||||||
/core/assets/saves/
|
|
||||||
/out/
|
|
||||||
/core/assets-raw/fontgen/out/
|
|
||||||
|
|
||||||
version.properties
|
version.properties
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ buildscript{
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
|
//IMPORTANT NOTICE: any version of the plugin after 3.4.1 will break builds for every API level < 24, perhaps even higher.
|
||||||
|
//it appears abstract methods don't get desugared properly (if at all)
|
||||||
classpath 'com.android.tools.build:gradle:3.4.1'
|
classpath 'com.android.tools.build:gradle:3.4.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
package mindustry.ai;
|
||||||
|
|
||||||
|
import arc.func.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.world;
|
||||||
|
|
||||||
|
public class Astar{
|
||||||
|
public static final DistanceHeuristic manhattan = (x1, y1, x2, y2) -> Math.abs(x1 - x2) + Math.abs(y1 - y2);
|
||||||
|
|
||||||
|
private static final Array<Tile> out = new Array<>();
|
||||||
|
private static final PQueue<Tile> queue = new PQueue<>(200 * 200 / 4, (a, b) -> 0);
|
||||||
|
private static final IntFloatMap costs = new IntFloatMap();
|
||||||
|
private static byte[][] rotations;
|
||||||
|
|
||||||
|
public static Array<Tile> pathfind(Tile from, Tile to, TileHueristic th, Boolf<Tile> passable){
|
||||||
|
return pathfind(from.x, from.y, to.x, to.y, th, manhattan, passable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Array<Tile> pathfind(int startX, int startY, int endX, int endY, TileHueristic th, Boolf<Tile> passable){
|
||||||
|
return pathfind(startX, startY, endX, endY, th, manhattan, passable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Array<Tile> pathfind(int startX, int startY, int endX, int endY, TileHueristic th, DistanceHeuristic dh, Boolf<Tile> passable){
|
||||||
|
Tiles tiles = world.tiles;
|
||||||
|
|
||||||
|
Tile start = tiles.getn(startX, startY);
|
||||||
|
Tile end = tiles.getn(endX, endY);
|
||||||
|
|
||||||
|
GridBits closed = new GridBits(tiles.width, tiles.height);
|
||||||
|
|
||||||
|
costs.clear();
|
||||||
|
queue.clear();
|
||||||
|
queue.comparator = Structs.comparingFloat(a -> costs.get(a.pos(), 0f) + dh.cost(a.x, a.y, end.x, end.y));
|
||||||
|
queue.add(start);
|
||||||
|
if(rotations == null || rotations.length != world.width() || rotations[0].length != world.height()){
|
||||||
|
rotations = new byte[world.width()][world.height()];
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
while(!queue.empty()){
|
||||||
|
Tile next = queue.poll();
|
||||||
|
float baseCost = costs.get(next.pos(), 0f);
|
||||||
|
if(next == end){
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
closed.set(next.x, next.y);
|
||||||
|
for(Point2 point : Geometry.d4){
|
||||||
|
int newx = next.x + point.x, newy = next.y + point.y;
|
||||||
|
if(Structs.inBounds(newx, newy, tiles.width, tiles.height)){
|
||||||
|
Tile child = tiles.getn(newx, newy);
|
||||||
|
if(passable.get(child)){
|
||||||
|
float newCost = th.cost(next, child) + baseCost;
|
||||||
|
if(!closed.get(child.x, child.y)){
|
||||||
|
closed.set(child.x, child.y);
|
||||||
|
rotations[child.x][child.y] = child.relativeTo(next.x, next.y);
|
||||||
|
costs.put(child.pos(), newCost);
|
||||||
|
queue.add(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.clear();
|
||||||
|
|
||||||
|
if(!found) return out;
|
||||||
|
|
||||||
|
Tile current = end;
|
||||||
|
while(current != start){
|
||||||
|
out.add(current);
|
||||||
|
|
||||||
|
byte rot = rotations[current.x][current.y];
|
||||||
|
current = tiles.getn(current.x + Geometry.d4x[rot], current.y + Geometry.d4y[rot]);
|
||||||
|
}
|
||||||
|
|
||||||
|
out.reverse();
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface DistanceHeuristic{
|
||||||
|
float cost(int x1, int y1, int x2, int y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface TileHueristic{
|
||||||
|
float cost(Tile tile);
|
||||||
|
|
||||||
|
default float cost(Tile from, Tile tile){
|
||||||
|
return cost(tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1790,7 +1790,7 @@ public class Blocks implements ContentList{
|
|||||||
hasPower = true;
|
hasPower = true;
|
||||||
|
|
||||||
consumes.items(ItemStack.with(Items.copper, 500));
|
consumes.items(ItemStack.with(Items.copper, 500));
|
||||||
consumes.power(4f);
|
consumes.power(3f);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
dataProcessor = new ResearchBlock("data-processor"){{
|
dataProcessor = new ResearchBlock("data-processor"){{
|
||||||
|
|||||||
@@ -5,11 +5,10 @@ import arc.graphics.*;
|
|||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
|
import mindustry.ctype.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
|
||||||
@@ -184,9 +183,11 @@ public class Drawf{
|
|||||||
Draw.rect(Core.atlas.find("shape-3"), x, y - oy + length / 2f, width, length, width / 2f, oy, rotation - 90);
|
Draw.rect(Core.atlas.find("shape-3"), x, y - oy + length / 2f, width, length, width / 2f, oy, rotation - 90);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void construct(Tilec t, UnitType unit, float rotation, float progress, float speed, float time){
|
public static void construct(Tilec t, UnlockableContent content, float rotation, float progress, float speed, float time){
|
||||||
TextureRegion region = unit.icon(Cicon.full);
|
construct(t, content.icon(Cicon.full), rotation, progress, speed, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void construct(Tilec t, TextureRegion region, float rotation, float progress, float speed, float time){
|
||||||
Shaders.build.region = region;
|
Shaders.build.region = region;
|
||||||
Shaders.build.progress = progress;
|
Shaders.build.progress = progress;
|
||||||
Shaders.build.color.set(Pal.accent);
|
Shaders.build.color.set(Pal.accent);
|
||||||
@@ -204,64 +205,4 @@ public class Drawf{
|
|||||||
|
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void respawn(Tilec tile, float heat, float progress, float time, UnitType to, @Nullable Playerc player){
|
|
||||||
float x = tile.x(), y = tile.y();
|
|
||||||
progress = Mathf.clamp(progress);
|
|
||||||
|
|
||||||
Draw.color(Pal.darkMetal);
|
|
||||||
Lines.stroke(2f * heat);
|
|
||||||
Fill.poly(x, y, 4, 10f * heat);
|
|
||||||
|
|
||||||
Draw.reset();
|
|
||||||
if(player != null){
|
|
||||||
TextureRegion region = to.icon(Cicon.full);
|
|
||||||
|
|
||||||
Draw.color(0f, 0f, 0f, 0.4f * progress);
|
|
||||||
Draw.rect("circle-shadow", x, y, region.getWidth() / 3f, region.getWidth() / 3f);
|
|
||||||
Draw.color();
|
|
||||||
|
|
||||||
Shaders.build.region = region;
|
|
||||||
Shaders.build.progress = progress;
|
|
||||||
Shaders.build.color.set(Pal.accent);
|
|
||||||
Shaders.build.time = -time / 10f;
|
|
||||||
|
|
||||||
Draw.shader(Shaders.build, true);
|
|
||||||
Draw.rect(region, x, y);
|
|
||||||
Draw.shader();
|
|
||||||
|
|
||||||
Draw.color(Pal.accentBack);
|
|
||||||
|
|
||||||
float pos = Mathf.sin(time, 6f, 8f);
|
|
||||||
|
|
||||||
Lines.lineAngleCenter(x + pos, y, 90, 16f - Math.abs(pos) * 2f);
|
|
||||||
|
|
||||||
Draw.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
Lines.stroke(2f * heat);
|
|
||||||
|
|
||||||
Draw.color(Pal.accentBack);
|
|
||||||
Lines.poly(x, y, 4, 8f * heat);
|
|
||||||
|
|
||||||
float oy = -7f, len = 6f * heat;
|
|
||||||
Lines.stroke(5f);
|
|
||||||
Draw.color(Pal.darkMetal);
|
|
||||||
Lines.line(x - len, y + oy, x + len, y + oy, CapStyle.none);
|
|
||||||
for(int i : Mathf.signs){
|
|
||||||
Fill.tri(x + len * i, y + oy - Lines.getStroke()/2f, x + len * i, y + oy + Lines.getStroke()/2f, x + (len + Lines.getStroke() * heat) * i, y + oy);
|
|
||||||
}
|
|
||||||
|
|
||||||
Lines.stroke(3f);
|
|
||||||
Draw.color(Pal.accent);
|
|
||||||
Lines.line(x - len, y + oy, x - len + len*2 * progress, y + oy, CapStyle.none);
|
|
||||||
for(int i : Mathf.signs){
|
|
||||||
Fill.tri(x + len * i, y + oy - Lines.getStroke()/2f, x + len * i, y + oy + Lines.getStroke()/2f, x + (len + Lines.getStroke() * heat) * i, y + oy);
|
|
||||||
}
|
|
||||||
Draw.reset();
|
|
||||||
|
|
||||||
if(Vars.net.active() && player != null){
|
|
||||||
tile.block().drawPlaceText(player.name(), tile.tileX(), tile.tileY() - (Math.max((tile.block().size-1)/2, 0)), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,15 +202,15 @@ public class DesktopInput extends InputHandler{
|
|||||||
shouldShoot = false;
|
shouldShoot = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Core.input.keyDown(Binding.respawn) && !player.dead() && !player.unit().spawnedByCore()){
|
|
||||||
Call.onUnitClear(player);
|
|
||||||
controlledType = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!player.dead() && !state.isPaused() && !(Core.scene.getKeyboardFocus() instanceof TextField)){
|
if(!player.dead() && !state.isPaused() && !(Core.scene.getKeyboardFocus() instanceof TextField)){
|
||||||
updateMovement(player.unit());
|
updateMovement(player.unit());
|
||||||
|
|
||||||
|
if(Core.input.keyDown(Binding.respawn) && !player.unit().spawnedByCore()){
|
||||||
|
Call.onUnitClear(player);
|
||||||
|
controlledType = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Core.input.keyRelease(Binding.select)){
|
if(Core.input.keyRelease(Binding.select)){
|
||||||
|
|||||||
@@ -273,12 +273,4 @@ public class Placement{
|
|||||||
return y + (x2 - x > y2 - y ? 0 : i);
|
return y + (x2 - x > y2 - y ? 0 : i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface DistanceHeuristic{
|
|
||||||
float cost(int x1, int y1, int x2, int y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface TileHueristic{
|
|
||||||
float cost(Tile tile, Tile other);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,70 @@
|
|||||||
package mindustry.maps.generators;
|
package mindustry.maps.generators;
|
||||||
|
|
||||||
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
|
import mindustry.ai.*;
|
||||||
|
import mindustry.content.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
import mindustry.world.blocks.production.*;
|
||||||
|
import mindustry.world.blocks.storage.*;
|
||||||
|
|
||||||
|
//makes terrible bases
|
||||||
public class BaseGenerator{
|
public class BaseGenerator{
|
||||||
|
int width, height;
|
||||||
|
Cell[][] cells;
|
||||||
|
Queue<Tile> frontier;
|
||||||
|
Array<Tile> all;
|
||||||
|
ObjectMap<Item, Array<Tile>> resources;
|
||||||
|
Team team;
|
||||||
|
|
||||||
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){
|
||||||
|
if(true){
|
||||||
|
SeedBaseGenerator gen = new SeedBaseGenerator();
|
||||||
|
gen.generate(tiles, team, cores.first());
|
||||||
|
|
||||||
/*
|
return;
|
||||||
GridBits used = new GridBits(tiles.width, tiles.height);
|
}
|
||||||
Queue<Tile> frontier = new Queue<>();
|
|
||||||
|
this.team = team;
|
||||||
|
width = tiles.width;
|
||||||
|
height = tiles.height;
|
||||||
|
|
||||||
|
cells = new Cell[width][height];
|
||||||
|
for(int x = 0; x < width; x++){
|
||||||
|
for(int y = 0; y < height; y++){
|
||||||
|
cells[x][y] = new Cell();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
all = new Array<>();
|
||||||
|
frontier = new Queue<>();
|
||||||
for(Tile tile : cores){
|
for(Tile tile : cores){
|
||||||
frontier.add(tile);
|
frontier.add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = 2000;
|
int count = 10000;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
|
|
||||||
|
//create bounds
|
||||||
while(total++ < count){
|
while(total++ < count){
|
||||||
Tile tile = frontier.removeFirst();
|
Tile tile = frontier.removeFirst();
|
||||||
|
all.add(tile);
|
||||||
for(int i = 0; i < 4; i++){
|
for(int i = 0; i < 4; i++){
|
||||||
int cx = tile.x + Geometry.d4x[i], cy = tile.y + Geometry.d4y[i];
|
int cx = tile.x + Geometry.d4x[i], cy = tile.y + Geometry.d4y[i];
|
||||||
if(tiles.in(cx, cy) && !used.get(cx, cy)){
|
if(tiles.in(cx, cy) && !contained(cx, cy)){
|
||||||
Tile other = tiles.getn(cx, cy);
|
Tile other = tiles.getn(cx, cy);
|
||||||
|
|
||||||
if(!other.solid()){
|
if(!other.solid()){
|
||||||
frontier.addLast(other);
|
frontier.addLast(other);
|
||||||
}
|
}
|
||||||
used.set(cx, cy);
|
cells[cx][cy].contained = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//walls, mostly for debugging
|
||||||
for(Tile tile : frontier){
|
for(Tile tile : frontier){
|
||||||
tile.setBlock(Blocks.copperWall, team);
|
tile.setBlock(Blocks.copperWall, team);
|
||||||
}
|
}
|
||||||
@@ -41,9 +72,69 @@ public class BaseGenerator{
|
|||||||
for(Tile tile : cores){
|
for(Tile tile : cores){
|
||||||
tile.clearOverlay();
|
tile.clearOverlay();
|
||||||
tile.setBlock(Blocks.coreShard, team);
|
tile.setBlock(Blocks.coreShard, team);
|
||||||
|
}
|
||||||
|
|
||||||
}*/
|
Block pump = Blocks.mechanicalPump;
|
||||||
|
Drill drill = (Drill)Blocks.pneumaticDrill;
|
||||||
|
resources = new ObjectMap<>();
|
||||||
|
|
||||||
|
//assign resource collection points
|
||||||
|
for(Tile tile : all){
|
||||||
|
//place drills.
|
||||||
|
if(tile.drop() != null && tile.drop().type == ItemType.material && tile.drop().hardness <= drill.tier && Build.validPlace(team, tile.x, tile.y, drill, 0)){
|
||||||
|
tile.setBlock(drill, team);
|
||||||
|
|
||||||
|
//mark item outputs
|
||||||
|
tile.getLinkedTiles(t -> {
|
||||||
|
cell(t).item = tile.drop();
|
||||||
|
resources.get(tile.drop(), Array::new).add(t);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//only water matters right now
|
||||||
|
//pumps are only placed on edges of water, even if it's shallow
|
||||||
|
if(tile.floor().liquidDrop == Liquids.water && Build.validPlace(team, tile.x, tile.y, pump, 0) && Build.contactsGround(tile.x, tile.y, pump)){
|
||||||
|
tile.setBlock(pump, team);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//clear path for cores
|
||||||
|
for(Tile start : cores){
|
||||||
|
Array<Tile> path = Astar.pathfind(start, spawn, (tile) -> tile.solid() ? 30f : 0f, tile -> !tile.block().isStatic() && !tile.floor().isDeep());
|
||||||
|
|
||||||
|
for(Tile tile : path){
|
||||||
|
tile.circle(2, (x, y) -> {
|
||||||
|
Tile t = tiles.getn(x, y);
|
||||||
|
if(t.team() == team && t.solid() && !(t.block() instanceof CoreBlock)){
|
||||||
|
t.setAir();
|
||||||
|
}
|
||||||
|
cell(t).taken = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item contactRes(Tile tile){
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
if(tile.getNearby(i) == null) continue;
|
||||||
|
Cell cell = cell(tile.getNearby(i));
|
||||||
|
if(cell.item != null) return cell.item;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cell cell(Tile tile){
|
||||||
|
return cells[tile.x][tile.y];
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean contained(int x, int y){
|
||||||
|
return cells[x][y].contained;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Cell{
|
||||||
|
boolean contained;
|
||||||
|
boolean taken;
|
||||||
|
Item item;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,14 @@ import arc.math.geom.*;
|
|||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
|
import mindustry.ai.*;
|
||||||
|
import mindustry.ai.Astar.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public abstract class BasicGenerator implements WorldGenerator{
|
public abstract class BasicGenerator implements WorldGenerator{
|
||||||
protected static final DistanceHeuristic manhattan = (x1, y1, x2, y2) -> Math.abs(x1 - x2) + Math.abs(y1 - y2);
|
|
||||||
protected static final ShortArray ints1 = new ShortArray(), ints2 = new ShortArray();
|
protected static final ShortArray ints1 = new ShortArray(), ints2 = new ShortArray();
|
||||||
|
|
||||||
protected Rand rand = new Rand();
|
protected Rand rand = new Rand();
|
||||||
@@ -313,50 +314,7 @@ public abstract class BasicGenerator implements WorldGenerator{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Array<Tile> pathfind(int startX, int startY, int endX, int endY, TileHueristic th, DistanceHeuristic dh){
|
public Array<Tile> pathfind(int startX, int startY, int endX, int endY, TileHueristic th, DistanceHeuristic dh){
|
||||||
Tile start = tiles.getn(startX, startY);
|
return Astar.pathfind(startX, startY, endX, endY, th, dh, tile -> world.getDarkness(tile.x, tile.y) <= 1f);
|
||||||
Tile end = tiles.getn(endX, endY);
|
|
||||||
GridBits closed = new GridBits(width, height);
|
|
||||||
IntFloatMap costs = new IntFloatMap();
|
|
||||||
PQueue<Tile> queue = new PQueue<>(tiles.width * tiles.height / 4, Structs.comparingFloat(a -> costs.get(a.pos(), 0f) + dh.cost(a.x, a.y, end.x, end.y)));
|
|
||||||
queue.add(start);
|
|
||||||
boolean found = false;
|
|
||||||
while(!queue.empty()){
|
|
||||||
Tile next = queue.poll();
|
|
||||||
float baseCost = costs.get(next.pos(), 0f);
|
|
||||||
if(next == end){
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
closed.set(next.x, next.y);
|
|
||||||
for(Point2 point : Geometry.d4){
|
|
||||||
int newx = next.x + point.x, newy = next.y + point.y;
|
|
||||||
if(Structs.inBounds(newx, newy, width, height) && world.getDarkness(newx, newy) <= 1f){
|
|
||||||
Tile child = tiles.getn(newx, newy);
|
|
||||||
float newCost = th.cost(child) + baseCost;
|
|
||||||
if(!closed.get(child.x, child.y)){
|
|
||||||
closed.set(child.x, child.y);
|
|
||||||
child.rotation(child.relativeTo(next.x, next.y));
|
|
||||||
costs.put(child.pos(), newCost);
|
|
||||||
queue.add(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Array<Tile> out = new Array<>();
|
|
||||||
|
|
||||||
if(!found) return out;
|
|
||||||
|
|
||||||
Tile current = end;
|
|
||||||
while(current != start){
|
|
||||||
out.add(current);
|
|
||||||
Point2 p = Geometry.d4(current.rotation());
|
|
||||||
current = tiles.getn(current.x + p.x, current.y + p.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
out.reverse();
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void trimDark(){
|
public void trimDark(){
|
||||||
@@ -397,12 +355,4 @@ public abstract class BasicGenerator implements WorldGenerator{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface DistanceHeuristic{
|
|
||||||
float cost(int x1, int y1, int x2, int y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface TileHueristic{
|
|
||||||
float cost(Tile tile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,266 @@
|
|||||||
|
package mindustry.maps.generators;
|
||||||
|
|
||||||
|
import arc.func.*;
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import mindustry.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.game.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
import mindustry.world.blocks.defense.*;
|
||||||
|
import mindustry.world.blocks.defense.turrets.*;
|
||||||
|
import mindustry.world.blocks.power.*;
|
||||||
|
import mindustry.world.blocks.production.*;
|
||||||
|
import mindustry.world.blocks.storage.*;
|
||||||
|
import mindustry.world.blocks.units.*;
|
||||||
|
import mindustry.world.consumers.*;
|
||||||
|
|
||||||
|
//makes terrible seeded bases
|
||||||
|
public class SeedBaseGenerator{
|
||||||
|
private final static int coreDst = 200;
|
||||||
|
|
||||||
|
private Team team;
|
||||||
|
private Rand rand = new Rand();
|
||||||
|
private Tiles tiles;
|
||||||
|
|
||||||
|
public void generate(Tiles tiles, Team team, Tile core){
|
||||||
|
this.team = team;
|
||||||
|
this.tiles = tiles;
|
||||||
|
|
||||||
|
float difficulty = 1f;
|
||||||
|
|
||||||
|
core.setBlock(Blocks.coreShard, team);
|
||||||
|
rand.nextBoolean();
|
||||||
|
|
||||||
|
float difficultyScl = Mathf.clamp(difficulty / 20f + rand.range(0.25f), 0f, 0.9999f);
|
||||||
|
float dscl2 = Mathf.clamp(0.5f + difficulty / 20f + rand.range(0.1f), 0f, 1.5f);
|
||||||
|
|
||||||
|
Array<Block> turrets = find(b -> b instanceof ItemTurret);
|
||||||
|
Array<Block> powerTurrets = find(b -> b instanceof PowerTurret);
|
||||||
|
Array<Block> walls = find(b -> b instanceof Wall && !(b instanceof Door) && b.size == 1);
|
||||||
|
Array<Block> drills = find(b -> b instanceof Drill && !b.consumes.has(ConsumeType.power));
|
||||||
|
Array<Block> powerDrills = find(b -> b instanceof Drill && b.consumes.has(ConsumeType.power));
|
||||||
|
|
||||||
|
Block wall = walls.get((int)(difficultyScl * walls.size));
|
||||||
|
|
||||||
|
Turret powerTurret = (Turret)powerTurrets.get((int)(difficultyScl * powerTurrets.size));
|
||||||
|
Turret bigTurret = (Turret)turrets.get(Mathf.clamp((int)((difficultyScl + 0.2f + rand.range(0.2f)) * turrets.size), 0, turrets.size-1));
|
||||||
|
Turret turret1 = (Turret)turrets.get(Mathf.clamp((int)((difficultyScl + rand.range(0.2f)) * turrets.size), 0, turrets.size-1));
|
||||||
|
Turret turret2 = (Turret)turrets.get(Mathf.clamp((int)((difficultyScl + rand.range(0.2f)) * turrets.size), 0, turrets.size-1));
|
||||||
|
Drill drill = (Drill)drills.get((int)(difficultyScl * drills.size));
|
||||||
|
Drill powerDrill = (Drill)powerDrills.get((int)(difficultyScl * powerDrills.size));
|
||||||
|
float placeChance = difficultyScl*0.75f+0.25f;
|
||||||
|
|
||||||
|
IntIntMap ammoPerType = new IntIntMap();
|
||||||
|
for(Block turret : turrets){
|
||||||
|
if(!(turret instanceof ItemTurret)) continue;
|
||||||
|
ItemTurret t = (ItemTurret)turret;
|
||||||
|
int size = t.ammoTypes.size;
|
||||||
|
ammoPerType.put(t.id, Mathf.clamp((int)(size* difficultyScl) + rand.range(1), 0, size - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
Func3<Tile, Block, Boolf<Tile>, Boolean> checker = (current, block, pred) -> {
|
||||||
|
for(Point2 point : Edges.getEdges(block.size)){
|
||||||
|
Tile tile = tiles.get(current.x + point.x, current.y + point.y);
|
||||||
|
if(tile != null){
|
||||||
|
if(tile.team() == team && pred.get(tile)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Func2<Block, Boolf<Tile>, Intc2> seeder = (block, pred) -> (x, y) -> {
|
||||||
|
if(canPlace(x, y, block) && ((block instanceof Wall && block.size == 1) || rand.chance(placeChance)) && checker.get(tiles.get(x, y), block, pred)){
|
||||||
|
setBlock(x, y, block);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Func2<Block, Float, Intc2> placer = (block, chance) -> (x, y) -> {
|
||||||
|
if(canPlace(x, y, block) && rand.chance(chance)){
|
||||||
|
setBlock(x, y, block);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Array<Intc2> passes = Array.with(
|
||||||
|
//initial seeding solar panels
|
||||||
|
(x, y) -> {
|
||||||
|
Block block = Blocks.largeSolarPanel;
|
||||||
|
|
||||||
|
if(rand.chance(0.001*placeChance) && canPlace(x, y, block)){
|
||||||
|
setBlock(x, y, block);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//extra seeding
|
||||||
|
seeder.get(Blocks.solarPanel, tile -> tile.block() == Blocks.largeSolarPanel && rand.chance(0.3)),
|
||||||
|
|
||||||
|
//drills (not powered)
|
||||||
|
(x, y) -> {
|
||||||
|
//if(!rand.chance(0.1*placeChance)) return;
|
||||||
|
|
||||||
|
Item item = drillItem(x, y, drill);
|
||||||
|
if(item != null && item != Items.sand && canPlace(x, y, drill)){
|
||||||
|
setBlock(x, y, drill);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//pump
|
||||||
|
(x, y) -> {
|
||||||
|
if(!rand.chance(0.1*placeChance)) return;
|
||||||
|
|
||||||
|
if(tiles.get(x, y).floor().isLiquid && tiles.get(x, y).floor().liquidDrop == Liquids.water){
|
||||||
|
setBlock(x, y, Blocks.mechanicalPump);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//coal gens
|
||||||
|
seeder.get(Blocks.combustionGenerator, tile -> tile.block() instanceof Drill && drillItem(tile.entity.tileX(), tile.entity.tileY(), (Drill)tile.block()) == Items.coal && rand.chance(0.2)),
|
||||||
|
|
||||||
|
//drills (powered)
|
||||||
|
(x, y) -> {
|
||||||
|
if(canPlace(x, y, powerDrill) && drillItem(x, y, powerDrill) == Items.thorium && checker.get(tiles.get(x, y), powerDrill, other -> other.block() instanceof PowerGenerator)){
|
||||||
|
setBlock(x, y, powerDrill);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//water extractors
|
||||||
|
seeder.get(Blocks.waterExtractor, tile -> tile.block() instanceof NuclearReactor && rand.chance(0.5)),
|
||||||
|
|
||||||
|
//mend projectors
|
||||||
|
seeder.get(Blocks.mendProjector, tile -> tile.block() instanceof PowerGenerator && rand.chance(0.04)),
|
||||||
|
|
||||||
|
//power turrets
|
||||||
|
seeder.get(powerTurret, tile -> tile.block() instanceof PowerGenerator && rand.chance(0.04)),
|
||||||
|
|
||||||
|
//repair point
|
||||||
|
seeder.get(Blocks.repairPoint, tile -> tile.block() instanceof PowerGenerator && rand.chance(0.1)),
|
||||||
|
|
||||||
|
//turrets1
|
||||||
|
seeder.get(turret1, tile -> tile.block() instanceof Drill && rand.chance(0.12)),
|
||||||
|
|
||||||
|
//turrets2
|
||||||
|
seeder.get(turret2, tile -> tile.block() instanceof Drill && rand.chance(0.12)),
|
||||||
|
|
||||||
|
//shields
|
||||||
|
seeder.get(Blocks.forceProjector, tile -> (tile.block() instanceof CoreBlock || tile.block() instanceof UnitFactory) && rand.chance(0.2 * dscl2)),
|
||||||
|
|
||||||
|
//unit pads (assorted)
|
||||||
|
//seeder.get(Blocks.daggerFactory, tile -> (tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector) && rand.chance(0.3 * dscl2)),
|
||||||
|
|
||||||
|
//unit pads (assorted)
|
||||||
|
//seeder.get(Blocks.wraithFactory, tile -> (tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector) && rand.chance(0.3 * dscl2)),
|
||||||
|
|
||||||
|
//unit pads (assorted)
|
||||||
|
//seeder.get(Blocks.titanFactory, tile -> (tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector) && rand.chance(0.23 * dscl2)),
|
||||||
|
|
||||||
|
//unit pads (assorted)
|
||||||
|
//seeder.get(Blocks.ghoulFactory, tile -> (tile.block() instanceof MendProjector || tile.block() instanceof ForceProjector) && rand.chance(0.23 * dscl2)),
|
||||||
|
|
||||||
|
//vaults
|
||||||
|
seeder.get(Blocks.vault, tile -> (tile.block() instanceof CoreBlock || tile.block() instanceof ForceProjector) && rand.chance(0.4)),
|
||||||
|
|
||||||
|
//big turrets
|
||||||
|
seeder.get(bigTurret, tile -> tile.block() instanceof StorageBlock && rand.chance(0.65)),
|
||||||
|
|
||||||
|
//walls
|
||||||
|
(x, y) -> {
|
||||||
|
if(!canPlace(x, y, wall)) return;
|
||||||
|
|
||||||
|
for(Point2 point : Geometry.d8){
|
||||||
|
Tile tile = tiles.get(x + point.x, y + point.y);
|
||||||
|
if(tile != null){
|
||||||
|
//tile = tile.target();
|
||||||
|
if(tile.team() == team && !(tile.block() instanceof Wall) && !(tile.block() instanceof UnitFactory)){
|
||||||
|
tiles.get(x, y).setBlock(wall, team);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//mines
|
||||||
|
placer.get(Blocks.shockMine, 0.02f * difficultyScl),
|
||||||
|
|
||||||
|
//fill up turrets w/ ammo
|
||||||
|
(x, y) -> {
|
||||||
|
Tile tile = tiles.get(x, y);
|
||||||
|
Block block = tile.block();
|
||||||
|
|
||||||
|
if(block instanceof ItemTurret){
|
||||||
|
ItemTurret turret = (ItemTurret)block;
|
||||||
|
for(Item item : turret.ammoTypes.keys()){
|
||||||
|
tile.entity.handleStack(item, tile.entity.acceptStack(item, 100, null), null);
|
||||||
|
}
|
||||||
|
}else if(block instanceof NuclearReactor){
|
||||||
|
tile.entity.items().add(Items.thorium, 30);
|
||||||
|
}else if(block instanceof LiquidTurret){
|
||||||
|
tile.entity.liquids().add(Liquids.water, tile.block().liquidCapacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
for(Intc2 i : passes){
|
||||||
|
for(int x = 0; x < tiles.width; x++){
|
||||||
|
for(int y = 0; y < tiles.height; y++){
|
||||||
|
if(!Mathf.within(x, y, core.x, core.y, coreDst)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.get(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item drillItem(int x, int y, Drill block){
|
||||||
|
if(block.isMultiblock()){
|
||||||
|
Item result = null;
|
||||||
|
int offsetx = -(block.size - 1) / 2;
|
||||||
|
int offsety = -(block.size - 1) / 2;
|
||||||
|
|
||||||
|
for(int dx = 0; dx < block.size; dx++){
|
||||||
|
for(int dy = 0; dy < block.size; dy++){
|
||||||
|
int worldx = dx + offsetx + x;
|
||||||
|
int worldy = dy + offsety + y;
|
||||||
|
if(!tiles.in(worldx, worldy)){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!block.canPlaceOn(tiles.get(worldx, worldy)) || tiles.get(worldx, worldy).drop() == null) continue;
|
||||||
|
|
||||||
|
Item drop = tiles.get(worldx, worldy).drop();
|
||||||
|
|
||||||
|
if(result == null || drop.id < result.id){
|
||||||
|
result = drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}else{
|
||||||
|
return tiles.get(x, y).drop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBlock(int x, int y, Block block){
|
||||||
|
tiles.get(x, y).setBlock(block, team);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean canPlace(int x, int y, Block block){
|
||||||
|
return Build.validPlace(team, x, y, block, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<Block> find(Boolf<Block> pred){
|
||||||
|
Array<Block> out = new Array<>();
|
||||||
|
for(Block block : Vars.content.blocks()){
|
||||||
|
if(pred.get(block) && block.isPlaceable()){
|
||||||
|
out.add(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import arc.math.geom.*;
|
|||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.noise.*;
|
import arc.util.noise.*;
|
||||||
|
import mindustry.ai.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.maps.generators.*;
|
import mindustry.maps.generators.*;
|
||||||
@@ -131,7 +132,7 @@ public class TODOPlanetGenerator extends PlanetGenerator{
|
|||||||
connected.add(to);
|
connected.add(to);
|
||||||
float nscl = rand.random(20f, 60f);
|
float nscl = rand.random(20f, 60f);
|
||||||
int stroke = rand.random(4, 12);
|
int stroke = rand.random(4, 12);
|
||||||
brush(pathfind(x, y, to.x, to.y, tile -> (tile.solid() ? 5f : 0f) + noise(tile.x, tile.y, 1, 1, 1f / nscl) * 60, manhattan), stroke);
|
brush(pathfind(x, y, to.x, to.y, tile -> (tile.solid() ? 5f : 0f) + noise(tile.x, tile.y, 1, 1, 1f / nscl) * 60, Astar.manhattan), stroke);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -333,6 +333,16 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
|||||||
|
|
||||||
hide();
|
hide();
|
||||||
|
|
||||||
|
//save before launch.
|
||||||
|
if(control.saves.getCurrent() != null && state.isGame()){
|
||||||
|
try{
|
||||||
|
control.saves.getCurrent().save();
|
||||||
|
}catch(Throwable e){
|
||||||
|
e.printStackTrace();
|
||||||
|
ui.showException("[accent]" + Core.bundle.get("savefail"), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(mode == launch){
|
if(mode == launch){
|
||||||
launcher.launch();
|
launcher.launch();
|
||||||
zoom = 0.5f;
|
zoom = 0.5f;
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public class Build{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO should water blocks be placeable here?
|
//TODO should water blocks be placeable here?
|
||||||
if(/*!type.requiresWater && */!contactsGround(tile.x, tile.y, type)){
|
if(/*!type.requiresWater && */!contactsShallows(tile.x, tile.y, type)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ public class Build{
|
|||||||
return true;
|
return true;
|
||||||
}else{
|
}else{
|
||||||
return tile.interactable(team)
|
return tile.interactable(team)
|
||||||
&& contactsGround(tile.x, tile.y, type)
|
&& contactsShallows(tile.x, tile.y, type)
|
||||||
&& (!tile.floor().isDeep() || type.floating || type.requiresWater)
|
&& (!tile.floor().isDeep() || type.floating || type.requiresWater)
|
||||||
&& tile.floor().placeableOn
|
&& tile.floor().placeableOn
|
||||||
&& (!type.requiresWater || tile.floor().liquidDrop == Liquids.water)
|
&& (!type.requiresWater || tile.floor().liquidDrop == Liquids.water)
|
||||||
@@ -128,7 +128,22 @@ public class Build{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean contactsGround(int x, int y, Block block){
|
public static boolean contactsGround(int x, int y, Block block){
|
||||||
|
if(block.isMultiblock()){
|
||||||
|
for(Point2 point : Edges.getEdges(block.size)){
|
||||||
|
Tile tile = world.tile(x + point.x, y + point.y);
|
||||||
|
if(tile != null && !tile.floor().isLiquid) return true;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
for(Point2 point : Geometry.d4){
|
||||||
|
Tile tile = world.tile(x + point.x, y + point.y);
|
||||||
|
if(tile != null && !tile.floor().isLiquid) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean contactsShallows(int x, int y, Block block){
|
||||||
if(block.isMultiblock()){
|
if(block.isMultiblock()){
|
||||||
for(Point2 point : Edges.getInsideEdges(block.size)){
|
for(Point2 point : Edges.getInsideEdges(block.size)){
|
||||||
Tile tile = world.tile(x + point.x, y + point.y);
|
Tile tile = world.tile(x + point.x, y + point.y);
|
||||||
|
|||||||
@@ -246,6 +246,15 @@ public class Tile implements Position, QuadTreeObject{
|
|||||||
setOverlay(overlay);
|
setOverlay(overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Sets the block to air. */
|
||||||
|
public void setAir(){
|
||||||
|
setBlock(Blocks.air);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void circle(int radius, Intc2 cons){
|
||||||
|
Geometry.circle(x, y, world.width(), world.height(), radius, cons);
|
||||||
|
}
|
||||||
|
|
||||||
public void recache(){
|
public void recache(){
|
||||||
if(!headless && !world.isGenerating()){
|
if(!headless && !world.isGenerating()){
|
||||||
renderer.blocks.floor.recacheTile(this);
|
renderer.blocks.floor.recacheTile(this);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package mindustry.world.blocks.campaign;
|
package mindustry.world.blocks.campaign;
|
||||||
|
|
||||||
|
import arc.Graphics.*;
|
||||||
|
import arc.Graphics.Cursor.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
@@ -11,7 +13,7 @@ import mindustry.graphics.*;
|
|||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
|
|
||||||
import static mindustry.Vars.state;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class CoreLauncher extends Block{
|
public class CoreLauncher extends Block{
|
||||||
public int range = 1;
|
public int range = 1;
|
||||||
@@ -38,18 +40,23 @@ public class CoreLauncher extends Block{
|
|||||||
|
|
||||||
if(state.isCampaign() && consValid()){
|
if(state.isCampaign() && consValid()){
|
||||||
Vars.ui.planet.show(state.rules.sector, range, this);
|
Vars.ui.planet.show(state.rules.sector, range, this);
|
||||||
|
|
||||||
cons.trigger();
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cursor getCursor(){
|
||||||
|
return consValid() ? SystemCursor.hand : SystemCursor.arrow;
|
||||||
|
}
|
||||||
|
|
||||||
public void launch(){
|
public void launch(){
|
||||||
LaunchCorec ent = LaunchCoreEntity.create();
|
LaunchCorec ent = LaunchCoreEntity.create();
|
||||||
ent.set(this);
|
ent.set(this);
|
||||||
ent.block(Blocks.coreShard);
|
ent.block(Blocks.coreShard);
|
||||||
ent.lifetime(Vars.launchDuration);
|
ent.lifetime(Vars.launchDuration);
|
||||||
ent.add();
|
ent.add();
|
||||||
|
|
||||||
|
cons.trigger();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,11 +123,5 @@ public class CoreLauncher extends Block{
|
|||||||
Fx.rocketSmokeLarge.at(cx() + Mathf.range(r), cy() + Mathf.range(r), fin());
|
Fx.rocketSmokeLarge.at(cx() + Mathf.range(r), cy() + Mathf.range(r), fin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove(){
|
|
||||||
|
|
||||||
//TODO something
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,26 +124,7 @@ public class BlockForge extends PayloadAcceptor{
|
|||||||
Draw.rect(outRegion, x, y, rotdeg());
|
Draw.rect(outRegion, x, y, rotdeg());
|
||||||
|
|
||||||
if(recipe != null){
|
if(recipe != null){
|
||||||
Draw.draw(Layer.blockOver, () -> {
|
Draw.draw(Layer.blockOver, () -> Drawf.construct(this, recipe, 0, progress / recipe.buildCost, heat, time));
|
||||||
TextureRegion region = recipe.icon(Cicon.full);
|
|
||||||
|
|
||||||
Shaders.build.region = region;
|
|
||||||
Shaders.build.progress = progress / recipe.buildCost;
|
|
||||||
Shaders.build.color.set(Pal.accent);
|
|
||||||
Shaders.build.color.a = heat;
|
|
||||||
Shaders.build.time = -time / 20f;
|
|
||||||
|
|
||||||
Draw.shader(Shaders.build);
|
|
||||||
Draw.rect(region, x, y);
|
|
||||||
Draw.shader();
|
|
||||||
|
|
||||||
Draw.color(Pal.accent);
|
|
||||||
Draw.alpha(heat);
|
|
||||||
|
|
||||||
Lines.lineAngleCenter(x + Mathf.sin(time, 20f, Vars.tilesize / 2f * size - 2f), y, 90, size * Vars.tilesize - 4f);
|
|
||||||
|
|
||||||
Draw.reset();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
drawPayload();
|
drawPayload();
|
||||||
|
|||||||
Reference in New Issue
Block a user