From a2960f5c5070188cd915ef9d1673c567a7e73fe8 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 31 Aug 2018 23:19:36 -0400 Subject: [PATCH] Pathfind updates / Less reflection / Platform cleanup --- .../io/anuke/mindustry/AndroidLauncher.java | 5 -- .../sprites/blocks/turrets/turrets/fuse.png | Bin 715 -> 717 bytes core/src/Mindustry.gwt.xml | 3 - .../src/io/anuke/mindustry/core/Platform.java | 2 - .../maps/generation/FortressGenerator.java | 55 +++++++++++++----- .../maps/generation/WorldGenerator.java | 8 +++ .../pathfinding/AStarPathFinder.java | 41 +++++++------ .../pathfinding/FlowPathFinder.java | 7 ++- .../pathfinding/TilePathfinder.java | 3 +- core/src/io/anuke/mindustry/net/Packets.java | 6 +- .../io/anuke/mindustry/net/Streamable.java | 14 ++--- kryonet/src/io/anuke/kryonet/KryoServer.java | 9 +-- 12 files changed, 87 insertions(+), 66 deletions(-) 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 a204f941ad75920e9e80dc0398abfb9dcab9a483..f3dee7d114cf558918a675c3b271ff8efe1a36e7 100644 GIT binary patch delta 663 zcmV;I0%-lq1Xi>3x z6yVkCcZ~K=ew=?~;r|jaO%tYR5_z24#TOuAc^|cIUHld;K!j)e7S8r94#;KG0DzC5 z4gr7xV7*=+0N}VD0O0uAJtUenB$_p~fJmON7g@euWTJ@UdRSj8@$aeB3Ky2+WD#8i zW$fF$X!&}P?SB}3A9#JOnLIIhQUBa)9g6O1|&)DHCdMt^(r^Qupz`urCUs$_;}>@M@e zynKJjhou7s1QN{}pD(hAoDu+B#Bn_(`R5xYUgQg5#kqd>%K7GCei1oNae7~ocZ@!t zjMO>f!IbBlZbfOMy2y<{Q&(AJnVixgiiqS-@1H8WO_{a=-^O{OQVY*lr9cJFp$L2G#MNMw$KbA zl$87q`hNcV@4wvnLm+o~@B8k(_kAy?)oL|FoqD~_0N~!qk$(mNFNaGE0G>R4s72-K zQ2}q>zGw9P>5so3nfSj5Ow)vEngkxFy7&YHEPszWcdmYmCLqAeJr|dIE)Q^Q3jpx( z(-8nL0Ib{X0RUR<4glcf#(gBJWhAO)HGv48spMFul4BxCtKGrcYMx)GQcIjz&XY-W zF(~cbBszg73t2X3j4WlF(bY2xd5tKH%4*7%x0Q1YU0nny< ztetLn!3wqy&k#o9*cKeyLaW{3)rjDO#t4JP2<2D$bbq70`+40*Qhff4CwZj_uV(x3 z46i?2^TpBw1_%<>GT$#UiP#cV%T(Z>Z{?$hytp!l#g#eVJyKazoN~xJMvresQqHhH z=KU6{+AMbYT;!@~>nevVg9E_+i<>?YYK3E4c=q5zsW$Ok5ifSv7XmFH62qKev)F}W zTi8mUV}E}6BH$atoPk%Gpy?`xoGfHRU2B*#fqSBqWl4)p*1kTv&B0ZsA#jo^wToOl zEvM-oYkHi0PeYyNmrxajtqF3b3Va#~NtxD#Mt}OMIS?_KkX8kmk6r>)c>$S - - - 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 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) 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 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;