diff --git a/android/src/io/anuke/mindustry/AndroidLauncher.java b/android/src/io/anuke/mindustry/AndroidLauncher.java
index 30253a1d85..11ccfc62fb 100644
--- a/android/src/io/anuke/mindustry/AndroidLauncher.java
+++ b/android/src/io/anuke/mindustry/AndroidLauncher.java
@@ -60,11 +60,6 @@ public class AndroidLauncher extends PatchedAndroidApplication{
Platform.instance = new Platform(){
DateFormat format = SimpleDateFormat.getDateTimeInstance();
- @Override
- public boolean hasDiscord(){
- return isPackageInstalled("com.discord");
- }
-
@Override
public String format(Date date){
return format.format(date);
diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/fuse.png b/core/assets-raw/sprites/blocks/turrets/turrets/fuse.png
index a204f941ad..f3dee7d114 100644
Binary files a/core/assets-raw/sprites/blocks/turrets/turrets/fuse.png and b/core/assets-raw/sprites/blocks/turrets/turrets/fuse.png differ
diff --git a/core/src/Mindustry.gwt.xml b/core/src/Mindustry.gwt.xml
index 8fbf313c24..d6cae53798 100644
--- a/core/src/Mindustry.gwt.xml
+++ b/core/src/Mindustry.gwt.xml
@@ -10,12 +10,9 @@
-
-
-
diff --git a/core/src/io/anuke/mindustry/core/Platform.java b/core/src/io/anuke/mindustry/core/Platform.java
index 94a1bf9008..c96f05440a 100644
--- a/core/src/io/anuke/mindustry/core/Platform.java
+++ b/core/src/io/anuke/mindustry/core/Platform.java
@@ -37,8 +37,6 @@ public abstract class Platform {
public boolean canDonate(){
return false;
}
- /**Whether the user has Discord installed. Defaults to true if unknown.*/
- public boolean hasDiscord(){return true;}
/**Return the localized name for the locale. This is basically a workaround for GWT not supporting getName().*/
public String getLocaleName(Locale locale){
return locale.toString();
diff --git a/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java b/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java
index 3964aff127..7815d65028 100644
--- a/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java
+++ b/core/src/io/anuke/mindustry/maps/generation/FortressGenerator.java
@@ -1,13 +1,13 @@
package io.anuke.mindustry.maps.generation;
+import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Predicate;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.blocks.DistributionBlocks;
import io.anuke.mindustry.content.blocks.StorageBlocks;
import io.anuke.mindustry.game.Team;
-import io.anuke.mindustry.maps.generation.pathfinding.FlowPathFinder;
-import io.anuke.mindustry.maps.generation.pathfinding.TilePathfinder;
+import io.anuke.mindustry.maps.generation.pathfinding.AStarPathFinder;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Recipe;
@@ -17,10 +17,10 @@ import io.anuke.mindustry.world.blocks.defense.Door;
import io.anuke.mindustry.world.blocks.defense.Wall;
import io.anuke.mindustry.world.blocks.defense.turrets.ItemTurret;
import io.anuke.mindustry.world.blocks.defense.turrets.PowerTurret;
+import io.anuke.mindustry.world.blocks.distribution.Conveyor;
import io.anuke.mindustry.world.blocks.power.SolarGenerator;
import io.anuke.mindustry.world.blocks.production.Drill;
import io.anuke.mindustry.world.consumers.ConsumePower;
-import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Mathf;
public class FortressGenerator{
@@ -53,18 +53,9 @@ public class FortressGenerator{
Block wall = walls.get((int)(difficultyScl * walls.size));
Drill drill = (Drill) drills.get((int)(difficultyScl * drills.size));
+ Item[] items = {Items.copper, Items.lead};
- TilePathfinder finder = new FlowPathFinder(gen.tiles);
- Array out = new Array<>();
- finder.search(gen.tile(enemyX, enemyY - 1), t -> t.block().dropsItem(Items.copper), out);
- for (int i = 0; i < out.size - 1; i++) {
- Tile current = out.get(i);
- Tile next = out.get(i + 1);
- byte rotation = next.relativeTo(current.x, current.y);
- current.setBlock(DistributionBlocks.conveyor, team);
- current.setRotation(rotation);
- }
- /*
+ AStarPathFinder finder = new AStarPathFinder(gen.tiles);
//place down drills
for(int x = 0; x < gen.width; x++){
@@ -76,7 +67,39 @@ public class FortressGenerator{
Item item = gen.drillItem(x, y, drill);
Block generator = gens.get(gen.random.random(0, gens.size-1));
- if(item != null && item == Items.copper && gen.canPlace(x, y, drill) && !gen.random.chance(0.5)){
+ boolean contains = false;
+ if(item != null){
+ for(Item other : items){
+ if(other == item){
+ contains = true;
+ break;
+ }
+ }
+ }
+
+ if(item != null && contains && gen.canPlace(x, y, drill) && !gen.random.chance(0.5)){
+ Array out = new Array<>();
+ finder.search(gen.tile(x, y), gen.tile(enemyX, enemyY - 2),
+ tile -> (tile.block() instanceof Conveyor || (Math.abs(tile.x - enemyX) <= 2 && Math.abs(tile.y - enemyY) <= 2))
+ && (Math.abs(tile.x - enemyX) != Math.abs(tile.y - enemyY)),
+ out);
+
+ byte last = 0;
+ for (int i = 0; i < out.size; i++) {
+ Tile current = out.get(i);
+
+ if(i != out.size - 1){
+ Tile next = out.get(i + 1);
+ byte rotation = current.relativeTo(next.x, next.y);
+ current.setBlock(DistributionBlocks.conveyor, team);
+ current.setRotation(rotation);
+ last = rotation;
+ }else{
+ current.setBlock(DistributionBlocks.conveyor, team);
+ current.setRotation(last);
+ }
+ }
+
gen.setBlock(x, y, drill, team);
}else if(gen.canPlace(x, y, generator) && gen.random.chance(0.01)){
gen.setBlock(x, y, generator, team);
@@ -84,6 +107,8 @@ public class FortressGenerator{
}
}
+ /*
+
//Turret turret = (Turret) turrets.first();
//place down turrets
diff --git a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java
index 96a276858d..12f14fca34 100644
--- a/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java
+++ b/core/src/io/anuke/mindustry/maps/generation/WorldGenerator.java
@@ -220,6 +220,14 @@ public class WorldGenerator{
generateOres(tiles, sector.getSeed(), true, sector.ores);
+ for(int x = 0; x < tiles.length; x++){
+ for(int y = 0; y < tiles[0].length; y++){
+ Tile tile = tiles[x][y];
+
+ tile.updateOcclusion();
+ }
+ }
+
Generation gen = new Generation(sector, tiles, tiles.length, tiles[0].length, random);
for(Mission mission : sector.missions){
diff --git a/core/src/io/anuke/mindustry/maps/generation/pathfinding/AStarPathFinder.java b/core/src/io/anuke/mindustry/maps/generation/pathfinding/AStarPathFinder.java
index 912448908c..fb58086e75 100644
--- a/core/src/io/anuke/mindustry/maps/generation/pathfinding/AStarPathFinder.java
+++ b/core/src/io/anuke/mindustry/maps/generation/pathfinding/AStarPathFinder.java
@@ -1,8 +1,8 @@
package io.anuke.mindustry.maps.generation.pathfinding;
+import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.BinaryHeap;
-import com.badlogic.gdx.utils.IntMap;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
@@ -13,9 +13,10 @@ import io.anuke.ucore.util.Mathf;
//TODO
public class AStarPathFinder extends TilePathfinder{
- IntMap records = new IntMap<>();
+ NodeRecord[] records;
BinaryHeap openList;
NodeRecord current;
+ Predicate goal;
private int searchId;
private Tile end;
@@ -28,14 +29,20 @@ public class AStarPathFinder extends TilePathfinder{
public AStarPathFinder(Tile[][] tiles) {
super(tiles);
+ this.records = new NodeRecord[tiles.length * tiles[0].length];
this.openList = new BinaryHeap<>();
}
@Override
- public void search(Tile start, Predicate result, Array out){
+ public void search(Tile start, Tile end, Array out){
}
+ public void search(Tile start, Tile end, Predicate pred, Array out){
+ this.goal = pred;
+ searchNodePath(start, end, out);
+ }
+
public boolean searchNodePath(Tile startNode, Tile endNode, Array outPath) {
this.end = endNode;
@@ -61,7 +68,7 @@ public class AStarPathFinder extends TilePathfinder{
current.category = CLOSED;
// Terminate if we reached the goal node
- if (current.node == endNode) return true;
+ if (current.node == endNode || goal.test(current.node)) return true;
visitChildren(endNode);
@@ -126,7 +133,7 @@ public class AStarPathFinder extends TilePathfinder{
// Initialize the record for the start node and add it to the open list
NodeRecord startRecord = getNodeRecord(startNode);
startRecord.node = startNode;
- //startRecord.connection = null;
+ startRecord.from = null;
startRecord.costSoFar = 0;
addToOpenList(startRecord, estimate(startNode, endNode));
@@ -185,32 +192,28 @@ public class AStarPathFinder extends TilePathfinder{
protected void nodes(Tile current, Consumer cons){
if(obstacle(current)) return;
- for(int i = 0; i < 4; i ++){
- Tile n = current.getNearby(i);
+ for(GridPoint2 p : Geometry.d4){
+ int wx = current.x + p.x, wy = current.y + p.y;
+ Tile n = Mathf.inBounds(wx, wy, tiles) ? tiles[wx][wy] : null;
if(!obstacle(n)) cons.accept(n);
}
}
- protected Tile rel(Tile tile, int i){
- return tile.getNearby(Geometry.d8[Mathf.mod(i, 8)]);
- }
-
protected boolean obstacle(Tile tile){
- return tile == null || (tile.solid() && end.target() != tile && tile.target() != end);
+ return tile == null || (tile.solid() && end.target() != tile && tile.target() != end) || !tile.block().alwaysReplace;
}
protected float estimate(Tile tile, Tile other){
- return Math.abs(tile.worldx() - other.worldx()) + Math.abs(tile.worldy() - other.worldy());
- // (tile.occluded ? tilesize : 0) + (other.occluded ? tilesize : 0);
+ return goal.test(other) || goal.test(tile) ? Float.MIN_VALUE : Math.abs(tile.worldx() - other.worldx()) + Math.abs(tile.worldy() - other.worldy());
}
protected void generateNodePath(Tile startNode, Array outPath) {
// Work back along the path, accumulating nodes
- // outPath.clear();
+ outPath.clear();
while (current.from != null) {
outPath.add(current.node);
- current = records.get(indexOf(current.from));
+ current = records[(indexOf(current.from))];
}
outPath.add(startNode);
@@ -224,14 +227,14 @@ public class AStarPathFinder extends TilePathfinder{
}
protected NodeRecord getNodeRecord(Tile node) {
- if(!records.containsKey(indexOf(node))){
+ if(records[indexOf(node)] == null){
NodeRecord record = new NodeRecord();
record.node = node;
record.searchId = searchId;
- records.put(indexOf(node), record);
+ records[indexOf(node)] = record;
return record;
}else{
- NodeRecord record = records.get(indexOf(node));
+ NodeRecord record = records[indexOf(node)];
if(record.searchId != searchId){
record.category = UNVISITED;
record.searchId = searchId;
diff --git a/core/src/io/anuke/mindustry/maps/generation/pathfinding/FlowPathFinder.java b/core/src/io/anuke/mindustry/maps/generation/pathfinding/FlowPathFinder.java
index df6a42023e..aef01f0688 100644
--- a/core/src/io/anuke/mindustry/maps/generation/pathfinding/FlowPathFinder.java
+++ b/core/src/io/anuke/mindustry/maps/generation/pathfinding/FlowPathFinder.java
@@ -16,6 +16,11 @@ public class FlowPathFinder extends TilePathfinder{
this.weights = new float[tiles.length][tiles[0].length];
}
+ @Override
+ public void search(Tile start, Tile end, Array out){
+
+ }
+
public void search(Tile start, Predicate result, Array out){
Queue queue = new Queue<>();
@@ -34,7 +39,7 @@ public class FlowPathFinder extends TilePathfinder{
Tile tile = queue.first();
for(GridPoint2 point : Geometry.d4){
int nx = tile.x + point.x, ny = tile.y + point.y;
- if(inBounds(nx, ny) && weights[nx][ny] < weights[tile.x][tile.y] && tiles[nx][ny].passable()){
+ if(inBounds(nx, ny) && weights[nx][ny] < weights[tile.x][tile.y] - 1f && tiles[nx][ny].passable()){
weights[nx][ny] = weights[tile.x][tile.y] - 1;
queue.addLast(tiles[nx][ny]);
if(result.test(tiles[nx][ny])){
diff --git a/core/src/io/anuke/mindustry/maps/generation/pathfinding/TilePathfinder.java b/core/src/io/anuke/mindustry/maps/generation/pathfinding/TilePathfinder.java
index 98de454722..6c8c6ecaa2 100644
--- a/core/src/io/anuke/mindustry/maps/generation/pathfinding/TilePathfinder.java
+++ b/core/src/io/anuke/mindustry/maps/generation/pathfinding/TilePathfinder.java
@@ -2,7 +2,6 @@ package io.anuke.mindustry.maps.generation.pathfinding;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.world.Tile;
-import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.Mathf;
public abstract class TilePathfinder{
@@ -16,5 +15,5 @@ public abstract class TilePathfinder{
return Mathf.inBounds(x, y, tiles);
}
- public abstract void search(Tile start, Predicate result, Array out);
+ public abstract void search(Tile start, Tile end, Array out);
}
diff --git a/core/src/io/anuke/mindustry/net/Packets.java b/core/src/io/anuke/mindustry/net/Packets.java
index 9ea7c2cd4f..5532f0ac78 100644
--- a/core/src/io/anuke/mindustry/net/Packets.java
+++ b/core/src/io/anuke/mindustry/net/Packets.java
@@ -240,20 +240,20 @@ public class Packets{
public int id = lastid++;
public int total;
- public Class extends Streamable> type;
+ public byte type;
@Override
public void write(ByteBuffer buffer){
buffer.putInt(id);
buffer.putInt(total);
- buffer.put(Registrator.getID(type));
+ buffer.put(type);
}
@Override
public void read(ByteBuffer buffer){
id = buffer.getInt();
total = buffer.getInt();
- type = (Class extends Streamable>) Registrator.getByID(buffer.get()).type;
+ type = buffer.get();
}
}
diff --git a/core/src/io/anuke/mindustry/net/Streamable.java b/core/src/io/anuke/mindustry/net/Streamable.java
index a27ea42ced..7ad7910149 100644
--- a/core/src/io/anuke/mindustry/net/Streamable.java
+++ b/core/src/io/anuke/mindustry/net/Streamable.java
@@ -1,7 +1,5 @@
package io.anuke.mindustry.net;
-import com.badlogic.gdx.utils.reflect.ClassReflection;
-import com.badlogic.gdx.utils.reflect.ReflectionException;
import io.anuke.mindustry.net.Packets.StreamBegin;
import java.io.ByteArrayInputStream;
@@ -18,7 +16,7 @@ public class Streamable implements Packet{
public static class StreamBuilder{
public final int id;
- public final Class extends Streamable> type;
+ public final byte type;
public final int total;
public final ByteArrayOutputStream stream;
@@ -38,13 +36,9 @@ public class Streamable implements Packet{
}
public Streamable build(){
- try{
- Streamable s = ClassReflection.newInstance(type);
- s.stream = new ByteArrayInputStream(stream.toByteArray());
- return s;
- }catch(ReflectionException e){
- throw new RuntimeException(e);
- }
+ Streamable s = (Streamable) Registrator.getByID(type).constructor.get();
+ s.stream = new ByteArrayInputStream(stream.toByteArray());
+ return s;
}
public boolean isDone(){
diff --git a/kryonet/src/io/anuke/kryonet/KryoServer.java b/kryonet/src/io/anuke/kryonet/KryoServer.java
index 314ce52b75..9a06cce0a5 100644
--- a/kryonet/src/io/anuke/kryonet/KryoServer.java
+++ b/kryonet/src/io/anuke/kryonet/KryoServer.java
@@ -10,16 +10,13 @@ import com.esotericsoftware.kryonet.Listener.LagListener;
import com.esotericsoftware.kryonet.Server;
import com.esotericsoftware.kryonet.util.InputStreamSender;
import io.anuke.mindustry.Vars;
-import io.anuke.mindustry.net.Net;
+import io.anuke.mindustry.net.*;
import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.Net.ServerProvider;
-import io.anuke.mindustry.net.NetConnection;
-import io.anuke.mindustry.net.NetworkIO;
import io.anuke.mindustry.net.Packets.Connect;
import io.anuke.mindustry.net.Packets.Disconnect;
import io.anuke.mindustry.net.Packets.StreamBegin;
import io.anuke.mindustry.net.Packets.StreamChunk;
-import io.anuke.mindustry.net.Streamable;
import io.anuke.ucore.UCore;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Log;
@@ -184,7 +181,7 @@ public class KryoServer implements ServerProvider {
//send an object so the receiving side knows how to handle the following chunks
StreamBegin begin = new StreamBegin();
begin.total = stream.stream.available();
- begin.type = stream.getClass();
+ begin.type = Registrator.getID(stream.getClass());
connection.connection.sendTCP(begin);
id = begin.id;
}
@@ -200,7 +197,7 @@ public class KryoServer implements ServerProvider {
int cid;
StreamBegin begin = new StreamBegin();
begin.total = stream.stream.available();
- begin.type = stream.getClass();
+ begin.type = Registrator.getID(stream.getClass());
connection.send(begin, SendMode.tcp);
cid = begin.id;