mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-02-21 03:58:05 +07:00
Pathfind updates / Less reflection / Platform cleanup
This commit is contained in:
parent
565f8a2b4d
commit
a2960f5c50
@ -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 |
@ -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"/>
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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){
|
||||
|
@ -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;
|
||||
|
@ -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])){
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(){
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user