1
0
mirror of https://github.com/Anuken/Mindustry.git synced 2024-09-23 14:27:56 +03:00

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(){
DateFormat format = SimpleDateFormat.getDateTimeInstance();
@Override
public boolean hasDiscord(){
return isPackageInstalled("com.discord");
}
@Override
public String format(Date 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.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.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.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.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.maps.generation.WorldGenerator"/>
<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(){
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();

View File

@ -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<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);
}
/*
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<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);
}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

View File

@ -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){

View File

@ -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<NodeRecord> records = new IntMap<>();
NodeRecord[] records;
BinaryHeap<NodeRecord> openList;
NodeRecord current;
Predicate<Tile> 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<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) {
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<Tile> 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<Tile> 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;

View File

@ -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<Tile> out){
}
public void search(Tile start, Predicate<Tile> result, Array<Tile> out){
Queue<Tile> 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])){

View File

@ -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<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 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();
}
}

View File

@ -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);
Streamable s = (Streamable) Registrator.getByID(type).constructor.get();
s.stream = new ByteArrayInputStream(stream.toByteArray());
return s;
}catch(ReflectionException e){
throw new RuntimeException(e);
}
}
public boolean isDone(){

View File

@ -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;