Pathfind updates / Less reflection / Platform cleanup

This commit is contained in:
Anuken
2018-08-31 23:19:36 -04:00
parent 565f8a2b4d
commit a2960f5c50
12 changed files with 87 additions and 66 deletions

View File

@@ -60,11 +60,6 @@ public class AndroidLauncher extends PatchedAndroidApplication{
Platform.instance = new Platform(){ Platform.instance = new Platform(){
DateFormat format = SimpleDateFormat.getDateTimeInstance(); DateFormat format = SimpleDateFormat.getDateTimeInstance();
@Override
public boolean hasDiscord(){
return isPackageInstalled("com.discord");
}
@Override @Override
public String format(Date date){ public String format(Date date){
return format.format(date); return format.format(date);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 B

After

Width:  |  Height:  |  Size: 717 B

View File

@@ -10,12 +10,9 @@
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.core.GameState"/> <extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.core.GameState"/>
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.SaveFileVersion"/> <extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.SaveFileVersion"/>
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.ucore.entities.impl.EffectEntity"/> <extend-configuration-property name="gdx.reflect.include" value="io.anuke.ucore.entities.impl.EffectEntity"/>
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.net.Packets"/>
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.net.Packet"/>
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.effect"/> <extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.effect"/>
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.bullet.Bullet"/> <extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.bullet.Bullet"/>
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.Team"/> <extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.Team"/>
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.net.Streamable"/>
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.meta.BlockBar"/> <extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.meta.BlockBar"/>
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.maps.generation.WorldGenerator"/> <extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.maps.generation.WorldGenerator"/>
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.StatusController"/> <extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.StatusController"/>

View File

@@ -37,8 +37,6 @@ public abstract class Platform {
public boolean canDonate(){ public boolean canDonate(){
return false; 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().*/ /**Return the localized name for the locale. This is basically a workaround for GWT not supporting getName().*/
public String getLocaleName(Locale locale){ public String getLocaleName(Locale locale){
return locale.toString(); return locale.toString();

View File

@@ -1,13 +1,13 @@
package io.anuke.mindustry.maps.generation; package io.anuke.mindustry.maps.generation;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Predicate; import com.badlogic.gdx.utils.Predicate;
import io.anuke.mindustry.content.Items; import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.content.blocks.DistributionBlocks; import io.anuke.mindustry.content.blocks.DistributionBlocks;
import io.anuke.mindustry.content.blocks.StorageBlocks; import io.anuke.mindustry.content.blocks.StorageBlocks;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.maps.generation.pathfinding.FlowPathFinder; import io.anuke.mindustry.maps.generation.pathfinding.AStarPathFinder;
import io.anuke.mindustry.maps.generation.pathfinding.TilePathfinder;
import io.anuke.mindustry.type.AmmoType; import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Recipe; 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.Wall;
import io.anuke.mindustry.world.blocks.defense.turrets.ItemTurret; import io.anuke.mindustry.world.blocks.defense.turrets.ItemTurret;
import io.anuke.mindustry.world.blocks.defense.turrets.PowerTurret; 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.power.SolarGenerator;
import io.anuke.mindustry.world.blocks.production.Drill; import io.anuke.mindustry.world.blocks.production.Drill;
import io.anuke.mindustry.world.consumers.ConsumePower; import io.anuke.mindustry.world.consumers.ConsumePower;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
public class FortressGenerator{ public class FortressGenerator{
@@ -53,18 +53,9 @@ public class FortressGenerator{
Block wall = walls.get((int)(difficultyScl * walls.size)); Block wall = walls.get((int)(difficultyScl * walls.size));
Drill drill = (Drill) drills.get((int)(difficultyScl * drills.size)); Drill drill = (Drill) drills.get((int)(difficultyScl * drills.size));
Item[] items = {Items.copper, Items.lead};
TilePathfinder finder = new FlowPathFinder(gen.tiles); AStarPathFinder finder = new AStarPathFinder(gen.tiles);
Array<Tile> 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);
}
/*
//place down drills //place down drills
for(int x = 0; x < gen.width; x++){ for(int x = 0; x < gen.width; x++){
@@ -76,7 +67,39 @@ public class FortressGenerator{
Item item = gen.drillItem(x, y, drill); Item item = gen.drillItem(x, y, drill);
Block generator = gens.get(gen.random.random(0, gens.size-1)); 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<Tile> 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); gen.setBlock(x, y, drill, team);
}else if(gen.canPlace(x, y, generator) && gen.random.chance(0.01)){ }else if(gen.canPlace(x, y, generator) && gen.random.chance(0.01)){
gen.setBlock(x, y, generator, team); gen.setBlock(x, y, generator, team);
@@ -84,6 +107,8 @@ public class FortressGenerator{
} }
} }
/*
//Turret turret = (Turret) turrets.first(); //Turret turret = (Turret) turrets.first();
//place down turrets //place down turrets

View File

@@ -220,6 +220,14 @@ public class WorldGenerator{
generateOres(tiles, sector.getSeed(), true, sector.ores); 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); Generation gen = new Generation(sector, tiles, tiles.length, tiles[0].length, random);
for(Mission mission : sector.missions){ for(Mission mission : sector.missions){

View File

@@ -1,8 +1,8 @@
package io.anuke.mindustry.maps.generation.pathfinding; package io.anuke.mindustry.maps.generation.pathfinding;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.BinaryHeap; import com.badlogic.gdx.utils.BinaryHeap;
import com.badlogic.gdx.utils.IntMap;
import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects;
@@ -13,9 +13,10 @@ import io.anuke.ucore.util.Mathf;
//TODO //TODO
public class AStarPathFinder extends TilePathfinder{ public class AStarPathFinder extends TilePathfinder{
IntMap<NodeRecord> records = new IntMap<>(); NodeRecord[] records;
BinaryHeap<NodeRecord> openList; BinaryHeap<NodeRecord> openList;
NodeRecord current; NodeRecord current;
Predicate<Tile> goal;
private int searchId; private int searchId;
private Tile end; private Tile end;
@@ -28,14 +29,20 @@ public class AStarPathFinder extends TilePathfinder{
public AStarPathFinder(Tile[][] tiles) { public AStarPathFinder(Tile[][] tiles) {
super(tiles); super(tiles);
this.records = new NodeRecord[tiles.length * tiles[0].length];
this.openList = new BinaryHeap<>(); this.openList = new BinaryHeap<>();
} }
@Override @Override
public void search(Tile start, Predicate<Tile> result, Array<Tile> out){ public void search(Tile start, Tile end, Array<Tile> out){
} }
public void search(Tile start, Tile end, Predicate<Tile> pred, Array<Tile> out){
this.goal = pred;
searchNodePath(start, end, out);
}
public boolean searchNodePath(Tile startNode, Tile endNode, Array<Tile> outPath) { public boolean searchNodePath(Tile startNode, Tile endNode, Array<Tile> outPath) {
this.end = endNode; this.end = endNode;
@@ -61,7 +68,7 @@ public class AStarPathFinder extends TilePathfinder{
current.category = CLOSED; current.category = CLOSED;
// Terminate if we reached the goal node // 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); 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 // Initialize the record for the start node and add it to the open list
NodeRecord startRecord = getNodeRecord(startNode); NodeRecord startRecord = getNodeRecord(startNode);
startRecord.node = startNode; startRecord.node = startNode;
//startRecord.connection = null; startRecord.from = null;
startRecord.costSoFar = 0; startRecord.costSoFar = 0;
addToOpenList(startRecord, estimate(startNode, endNode)); addToOpenList(startRecord, estimate(startNode, endNode));
@@ -185,32 +192,28 @@ public class AStarPathFinder extends TilePathfinder{
protected void nodes(Tile current, Consumer<Tile> cons){ protected void nodes(Tile current, Consumer<Tile> cons){
if(obstacle(current)) return; if(obstacle(current)) return;
for(int i = 0; i < 4; i ++){ for(GridPoint2 p : Geometry.d4){
Tile n = current.getNearby(i); 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); 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){ 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){ protected float estimate(Tile tile, Tile other){
return Math.abs(tile.worldx() - other.worldx()) + Math.abs(tile.worldy() - other.worldy()); return goal.test(other) || goal.test(tile) ? Float.MIN_VALUE : Math.abs(tile.worldx() - other.worldx()) + Math.abs(tile.worldy() - other.worldy());
// (tile.occluded ? tilesize : 0) + (other.occluded ? tilesize : 0);
} }
protected void generateNodePath(Tile startNode, Array<Tile> outPath) { protected void generateNodePath(Tile startNode, Array<Tile> outPath) {
// Work back along the path, accumulating nodes // Work back along the path, accumulating nodes
// outPath.clear(); outPath.clear();
while (current.from != null) { while (current.from != null) {
outPath.add(current.node); outPath.add(current.node);
current = records.get(indexOf(current.from)); current = records[(indexOf(current.from))];
} }
outPath.add(startNode); outPath.add(startNode);
@@ -224,14 +227,14 @@ public class AStarPathFinder extends TilePathfinder{
} }
protected NodeRecord getNodeRecord(Tile node) { protected NodeRecord getNodeRecord(Tile node) {
if(!records.containsKey(indexOf(node))){ if(records[indexOf(node)] == null){
NodeRecord record = new NodeRecord(); NodeRecord record = new NodeRecord();
record.node = node; record.node = node;
record.searchId = searchId; record.searchId = searchId;
records.put(indexOf(node), record); records[indexOf(node)] = record;
return record; return record;
}else{ }else{
NodeRecord record = records.get(indexOf(node)); NodeRecord record = records[indexOf(node)];
if(record.searchId != searchId){ if(record.searchId != searchId){
record.category = UNVISITED; record.category = UNVISITED;
record.searchId = searchId; record.searchId = searchId;

View File

@@ -16,6 +16,11 @@ public class FlowPathFinder extends TilePathfinder{
this.weights = new float[tiles.length][tiles[0].length]; this.weights = new float[tiles.length][tiles[0].length];
} }
@Override
public void search(Tile start, Tile end, Array<Tile> out){
}
public void search(Tile start, Predicate<Tile> result, Array<Tile> out){ public void search(Tile start, Predicate<Tile> result, Array<Tile> out){
Queue<Tile> queue = new Queue<>(); Queue<Tile> queue = new Queue<>();
@@ -34,7 +39,7 @@ public class FlowPathFinder extends TilePathfinder{
Tile tile = queue.first(); Tile tile = queue.first();
for(GridPoint2 point : Geometry.d4){ for(GridPoint2 point : Geometry.d4){
int nx = tile.x + point.x, ny = tile.y + point.y; 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; weights[nx][ny] = weights[tile.x][tile.y] - 1;
queue.addLast(tiles[nx][ny]); queue.addLast(tiles[nx][ny]);
if(result.test(tiles[nx][ny])){ if(result.test(tiles[nx][ny])){

View File

@@ -2,7 +2,6 @@ package io.anuke.mindustry.maps.generation.pathfinding;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
public abstract class TilePathfinder{ public abstract class TilePathfinder{
@@ -16,5 +15,5 @@ public abstract class TilePathfinder{
return Mathf.inBounds(x, y, tiles); return Mathf.inBounds(x, y, tiles);
} }
public abstract void search(Tile start, Predicate<Tile> result, Array<Tile> out); public abstract void search(Tile start, Tile end, Array<Tile> out);
} }

View File

@@ -240,20 +240,20 @@ public class Packets{
public int id = lastid++; public int id = lastid++;
public int total; public int total;
public Class<? extends Streamable> type; public byte type;
@Override @Override
public void write(ByteBuffer buffer){ public void write(ByteBuffer buffer){
buffer.putInt(id); buffer.putInt(id);
buffer.putInt(total); buffer.putInt(total);
buffer.put(Registrator.getID(type)); buffer.put(type);
} }
@Override @Override
public void read(ByteBuffer buffer){ public void read(ByteBuffer buffer){
id = buffer.getInt(); id = buffer.getInt();
total = buffer.getInt(); total = buffer.getInt();
type = (Class<? extends Streamable>) Registrator.getByID(buffer.get()).type; type = buffer.get();
} }
} }

View File

@@ -1,7 +1,5 @@
package io.anuke.mindustry.net; 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 io.anuke.mindustry.net.Packets.StreamBegin;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@@ -18,7 +16,7 @@ public class Streamable implements Packet{
public static class StreamBuilder{ public static class StreamBuilder{
public final int id; public final int id;
public final Class<? extends Streamable> type; public final byte type;
public final int total; public final int total;
public final ByteArrayOutputStream stream; public final ByteArrayOutputStream stream;
@@ -38,13 +36,9 @@ public class Streamable implements Packet{
} }
public Streamable build(){ public Streamable build(){
try{ Streamable s = (Streamable) Registrator.getByID(type).constructor.get();
Streamable s = ClassReflection.newInstance(type); s.stream = new ByteArrayInputStream(stream.toByteArray());
s.stream = new ByteArrayInputStream(stream.toByteArray()); return s;
return s;
}catch(ReflectionException e){
throw new RuntimeException(e);
}
} }
public boolean isDone(){ public boolean isDone(){

View File

@@ -10,16 +10,13 @@ import com.esotericsoftware.kryonet.Listener.LagListener;
import com.esotericsoftware.kryonet.Server; import com.esotericsoftware.kryonet.Server;
import com.esotericsoftware.kryonet.util.InputStreamSender; import com.esotericsoftware.kryonet.util.InputStreamSender;
import io.anuke.mindustry.Vars; 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.SendMode;
import io.anuke.mindustry.net.Net.ServerProvider; 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.Connect;
import io.anuke.mindustry.net.Packets.Disconnect; import io.anuke.mindustry.net.Packets.Disconnect;
import io.anuke.mindustry.net.Packets.StreamBegin; import io.anuke.mindustry.net.Packets.StreamBegin;
import io.anuke.mindustry.net.Packets.StreamChunk; import io.anuke.mindustry.net.Packets.StreamChunk;
import io.anuke.mindustry.net.Streamable;
import io.anuke.ucore.UCore; import io.anuke.ucore.UCore;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Log; 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 //send an object so the receiving side knows how to handle the following chunks
StreamBegin begin = new StreamBegin(); StreamBegin begin = new StreamBegin();
begin.total = stream.stream.available(); begin.total = stream.stream.available();
begin.type = stream.getClass(); begin.type = Registrator.getID(stream.getClass());
connection.connection.sendTCP(begin); connection.connection.sendTCP(begin);
id = begin.id; id = begin.id;
} }
@@ -200,7 +197,7 @@ public class KryoServer implements ServerProvider {
int cid; int cid;
StreamBegin begin = new StreamBegin(); StreamBegin begin = new StreamBegin();
begin.total = stream.stream.available(); begin.total = stream.stream.available();
begin.type = stream.getClass(); begin.type = Registrator.getID(stream.getClass());
connection.send(begin, SendMode.tcp); connection.send(begin, SendMode.tcp);
cid = begin.id; cid = begin.id;