diff --git a/core/src/io/anuke/mindustry/ai/WaveSpawner.java b/core/src/io/anuke/mindustry/ai/WaveSpawner.java index f3a6eb49ed..44c39e1b59 100644 --- a/core/src/io/anuke/mindustry/ai/WaveSpawner.java +++ b/core/src/io/anuke/mindustry/ai/WaveSpawner.java @@ -113,7 +113,6 @@ public class WaveSpawner{ if(group.type.isFlying){ FlyerSpawn spawn = flySpawns.get(flyCount); - //TODO verify flyer spawn float margin = 40f; //how far away from the edge flying units spawn spawnX = world.width() * tilesize / 2f + Mathf.sqrwavex(spawn.angle) * (world.width() / 2f * tilesize + margin); diff --git a/core/src/io/anuke/mindustry/core/ContentLoader.java b/core/src/io/anuke/mindustry/core/ContentLoader.java index e9c3c2aaf8..030b22f349 100644 --- a/core/src/io/anuke/mindustry/core/ContentLoader.java +++ b/core/src/io/anuke/mindustry/core/ContentLoader.java @@ -176,7 +176,7 @@ public class ContentLoader{ } public void dispose(){ - //TODO clear all content. + //clear all content, currently not needed } public void handleContent(Content content){ diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 1222bde0da..aff70ff938 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -24,14 +24,10 @@ import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.ucore.core.*; -import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.EntityQuery; import io.anuke.ucore.modules.Module; import io.anuke.ucore.util.Atlas; -import io.anuke.ucore.util.Bundles; -import io.anuke.ucore.util.Strings; - -import java.io.IOException; +import io.anuke.ucore.util.Timer; import static io.anuke.mindustry.Vars.*; @@ -48,6 +44,7 @@ public class Control extends Module{ public final Saves saves; public final Unlocks unlocks; + private Timer timerRPC= new Timer(), timerUnlock = new Timer(); private boolean hiscore = false; private boolean wasPaused = false; private InputHandler[] inputs = {}; @@ -364,12 +361,12 @@ public class Control extends Module{ } //auto-update rpc every 5 seconds - if(Timers.get("rpcUpdate", 60 * 5)){ + if(timerRPC.get(60 * 5)){ Platform.instance.updateRPC(); } //check unlocks every 2 seconds - if(!state.mode.infiniteResources && Timers.get("timerCheckUnlock", 120)){ + if(!state.mode.infiniteResources && timerUnlock.get(120)){ checkUnlockableBlocks(); //save if the unlocks changed @@ -396,10 +393,6 @@ public class Control extends Module{ } } - if(!state.is(State.paused) || Net.active()){ - Entities.update(effectGroup); - Entities.update(groundEffectGroup); - } }else{ if(!state.is(State.paused) || Net.active()){ Timers.update(); diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index 175fde0dca..097082035f 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -164,6 +164,10 @@ public class Logic extends Module{ if(!Entities.defaultGroup().isEmpty()) throw new RuntimeException("Do not add anything to the default group!"); + if(!headless){ + Entities.update(effectGroup); + Entities.update(groundEffectGroup); + } for(EntityGroup group : unitGroups){ Entities.update(group); diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 5c5f543044..19957469f7 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -117,7 +117,7 @@ public class UI extends SceneModule{ } @Override - public synchronized void update(){ + public void update(){ if(Graphics.drawing()) Graphics.end(); act(); diff --git a/core/src/io/anuke/mindustry/entities/Damage.java b/core/src/io/anuke/mindustry/entities/Damage.java index 579dddc3df..23f00d7e10 100644 --- a/core/src/io/anuke/mindustry/entities/Damage.java +++ b/core/src/io/anuke/mindustry/entities/Damage.java @@ -47,7 +47,7 @@ public class Damage{ for(int i = 0; i < waves; i++){ int f = i; Timers.run(i * 2f, () -> { - Damage.damage(x, y, Mathf.clamp(radius + explosiveness, 0, 50f) * ((f + 1f) / waves), explosiveness / 2f); + threads.run(() -> Damage.damage(x, y, Mathf.clamp(radius + explosiveness, 0, 50f) * ((f + 1f) / waves), explosiveness / 2f)); Effects.effect(ExplosionFx.blockExplosionSmoke, x + Mathf.range(radius), y + Mathf.range(radius)); }); } diff --git a/core/src/io/anuke/mindustry/entities/Units.java b/core/src/io/anuke/mindustry/entities/Units.java index b5673b04bc..6b6ea0a4f2 100644 --- a/core/src/io/anuke/mindustry/entities/Units.java +++ b/core/src/io/anuke/mindustry/entities/Units.java @@ -11,6 +11,7 @@ import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.entities.EntityQuery; import io.anuke.ucore.function.Consumer; import io.anuke.ucore.function.Predicate; +import io.anuke.ucore.util.Threads; import io.anuke.ucore.util.EnumSet; import static io.anuke.mindustry.Vars.*; @@ -20,10 +21,11 @@ import static io.anuke.mindustry.Vars.*; */ public class Units{ private static Rectangle rect = new Rectangle(); + private static Rectangle rectGraphics = new Rectangle(); private static Rectangle hitrect = new Rectangle(); private static Unit result; private static float cdist; - private static boolean boolResult; + private static boolean boolResult, boolResultGraphics; /** * Validates a target. @@ -53,33 +55,57 @@ public class Units{ return invalidateTarget(target, targeter.team, targeter.x, targeter.y, targeter.getWeapon().getAmmo().getRange()); } - /** - * Returns whether there are any entities on this tile. - */ + /**Returns whether there are any entities on this tile.*/ public static boolean anyEntities(Tile tile){ Block type = tile.block(); rect.setSize(type.size * tilesize, type.size * tilesize); rect.setCenter(tile.drawx(), tile.drawy()); - boolResult = false; - - Units.getNearby(rect, unit -> { - if(boolResult) return; - if(!unit.isFlying()){ - unit.getHitbox(hitrect); - - if(hitrect.overlaps(rect)){ - boolResult = true; - } - } - }); - - return boolResult; + return anyEntities(rect); } - /** - * Returns whether there are any entities on this tile, with the hitbox expanded. - */ + /**Can be called from any thread.*/ + public static boolean anyEntities(Rectangle rect){ + if(Threads.isLogic()){ + boolResult = false; + + Units.getNearby(rect, unit -> { + if(boolResult) return; + if(!unit.isFlying()){ + unit.getHitbox(hitrect); + + if(hitrect.overlaps(rect)){ + boolResult = true; + } + } + }); + + return boolResult; + }else{ + boolResultGraphics = false; + + for(EntityGroup g : unitGroups){ + g.forEach(u -> { + u.getHitbox(rectGraphics); + if(rectGraphics.overlaps(rect)){ + boolResultGraphics = true; + } + }); + if(boolResultGraphics) return true; + } + + playerGroup.forEach(u -> { + u.getHitbox(rectGraphics); + if(rectGraphics.overlaps(rect)){ + boolResultGraphics = true; + } + }); + + return boolResultGraphics; + } + } + + /**Returns whether there are any entities on this tile, with the hitbox expanded.*/ public static boolean anyEntities(Tile tile, float expansion, Predicate pred){ Block type = tile.block(); rect.setSize(type.size * tilesize + expansion, type.size * tilesize + expansion); diff --git a/core/src/io/anuke/mindustry/graphics/Trail.java b/core/src/io/anuke/mindustry/graphics/Trail.java index f0f0d8bef4..1d5f3fade1 100644 --- a/core/src/io/anuke/mindustry/graphics/Trail.java +++ b/core/src/io/anuke/mindustry/graphics/Trail.java @@ -10,7 +10,7 @@ import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.util.Mathf; /** - * Class that renders a trail. + * Class that renders a colored trail. */ public class Trail{ private final static float maxJump = 15f; diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index c6113e7001..85626ab1f5 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -267,7 +267,6 @@ public abstract class InputHandler extends InputAdapter{ && tile.floor().drops != null && tile.floor().drops.item.hardness <= player.mech.drillPower && !tile.floor().playerUnmineable && player.inventory.canAcceptItem(tile.floor().drops.item) - && Units.getClosestEnemy(player.getTeam(), tile.worldx(), tile.worldy(), 40f, e -> true) == null //don't being mining when an enemy is near && tile.block() == Blocks.air && player.distanceTo(tile.worldx(), tile.worldy()) <= Player.mineDistance; } @@ -354,7 +353,7 @@ public abstract class InputHandler extends InputAdapter{ for(Tile tile : state.teams.get(player.getTeam()).cores){ if(tile.distanceTo(x * tilesize, y * tilesize) < coreBuildRange){ return Build.validPlace(player.getTeam(), x, y, type, rotation) && - Vector2.dst(player.x, player.y, x * tilesize, y * tilesize) < Player.placeDistance; + Vector2.dst(player.x, player.y, x * tilesize, y * tilesize) < Player.placeDistance; } } @@ -366,12 +365,10 @@ public abstract class InputHandler extends InputAdapter{ } public void placeBlock(int x, int y, Recipe recipe, int rotation){ - //todo multiplayer support player.addBuildRequest(new BuildRequest(x, y, rotation, recipe)); } public void breakBlock(int x, int y){ - //todo multiplayer support Tile tile = world.tile(x, y).target(); player.addBuildRequest(new BuildRequest(tile.x, tile.y)); } diff --git a/core/src/io/anuke/mindustry/input/MobileInput.java b/core/src/io/anuke/mindustry/input/MobileInput.java index 6b50423a75..1112e6599e 100644 --- a/core/src/io/anuke/mindustry/input/MobileInput.java +++ b/core/src/io/anuke/mindustry/input/MobileInput.java @@ -28,7 +28,6 @@ import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.*; -import io.anuke.ucore.entities.Entities; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.scene.Group; @@ -84,19 +83,17 @@ public class MobileInput extends InputHandler implements GestureListener{ /** Check and assign targets for a specific position. */ void checkTargets(float x, float y){ - synchronized(Entities.entityLock){ - Unit unit = Units.getClosestEnemy(player.getTeam(), x, y, 20f, u -> !u.isDead() && u.isAdded()); + Unit unit = Units.getClosestEnemy(player.getTeam(), x, y, 20f, u -> !u.isDead()); - if(unit != null){ - threads.run(() -> player.target = unit); - }else{ - Tile tile = world.tileWorld(x, y); - if(tile != null) tile = tile.target(); + if(unit != null){ + threads.run(() -> player.target = unit); + }else{ + Tile tile = world.tileWorld(x, y); + if(tile != null) tile = tile.target(); - if(tile != null && state.teams.areEnemies(player.getTeam(), tile.getTeam())){ - TileEntity entity = tile.entity; - threads.run(() -> player.target = entity); - } + if(tile != null && state.teams.areEnemies(player.getTeam(), tile.getTeam())){ + TileEntity entity = tile.entity; + threads.run(() -> player.target = entity); } } } @@ -344,7 +341,7 @@ public class MobileInput extends InputHandler implements GestureListener{ if(lineMode){ int tileX = tileX(Gdx.input.getX()); int tileY = tileY(Gdx.input.getY()); - + //draw placing if(mode == placing && recipe != null){ NormalizeDrawResult dresult = PlaceUtils.normalizeDrawArea(recipe.result, lineStartX, lineStartY, tileX, tileY, true, maxLength, lineScale); @@ -399,7 +396,7 @@ public class MobileInput extends InputHandler implements GestureListener{ Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y); } - + } TargetTrait target = player.target; @@ -555,7 +552,7 @@ public class MobileInput extends InputHandler implements GestureListener{ //ignore off-screen taps if(cursor == null || ui.hasMouse(x, y)) return false; - checkTargets(worldx, worldy); + threads.run(() -> checkTargets(worldx, worldy)); //remove if request present if(hasRequest(cursor)){ diff --git a/core/src/io/anuke/mindustry/maps/generation/pathfinding/AStarPathFinder.java b/core/src/io/anuke/mindustry/maps/generation/pathfinding/AStarPathFinder.java deleted file mode 100644 index 90c13e3063..0000000000 --- a/core/src/io/anuke/mindustry/maps/generation/pathfinding/AStarPathFinder.java +++ /dev/null @@ -1,267 +0,0 @@ -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 io.anuke.mindustry.content.fx.Fx; -import io.anuke.mindustry.world.Tile; -import io.anuke.ucore.core.Effects; -import io.anuke.ucore.function.Consumer; -import io.anuke.ucore.function.Predicate; -import io.anuke.ucore.util.Structs; -import io.anuke.ucore.util.Geometry; - -//TODO -public class AStarPathFinder extends TilePathfinder{ - NodeRecord[] records; - BinaryHeap openList; - NodeRecord current; - Predicate goal; - - private int searchId; - private Tile end; - - private static final byte UNVISITED = 0; - private static final byte OPEN = 1; - private static final byte CLOSED = 2; - - private static final boolean debug = false; - - 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, 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; - - // Perform AStar - boolean found = search(startNode, endNode); - - if (found) { - // Create a path made of nodes - generateNodePath(startNode, outPath); - } - - return found; - } - - protected boolean search(Tile startNode, Tile endNode) { - - initSearch(startNode, endNode); - - // Iterate through processing each node - do { - // Retrieve the node with smallest estimated total cost from the open list - current = openList.pop(); - current.category = CLOSED; - - // Terminate if we reached the goal node - if (current.node == endNode || goal.test(current.node)) return true; - - visitChildren(endNode); - - } while (openList.size > 0); - - // We've run out of nodes without finding the goal, so there's no solution - return false; - } -/* - public boolean search(PathFinderRequest request, long timeToRun) { - - long lastTime = TimeUtils.nanoTime(); - - // We have to initialize the search if the status has just changed - if (request.statusChanged) { - initSearch(request.startNode, request.endNode); - request.statusChanged = false; - } - - // Iterate through processing each node - do { - - // Check the available time - long currentTime = TimeUtils.nanoTime(); - timeToRun -= currentTime - lastTime; - if (timeToRun <= PathFinderQueue.TIME_TOLERANCE) return false; - - // Retrieve the node with smallest estimated total cost from the open list - current = openList.pop(); - current.category = CLOSED; - - // Terminate if we reached the goal node; we've found a path. - if (current.node == request.endNode) { - request.pathFound = true; - - generateNodePath(request.startNode, request.resultPath); - - return true; - } - - // Visit current node's children - visitChildren(request.endNode); - - // Store the current time - lastTime = currentTime; - - } while (openList.size > 0); - - // The open list is empty and we've not found a path. - request.pathFound = false; - return true; - }*/ - - protected void initSearch(Tile startNode, Tile endNode) { - - // Increment the search id - if (++searchId < 0) searchId = 1; - - // Initialize the open list - openList.clear(); - - // Initialize the record for the start node and add it to the open list - NodeRecord startRecord = getNodeRecord(startNode); - startRecord.node = startNode; - startRecord.from = null; - startRecord.costSoFar = 0; - addToOpenList(startRecord, estimate(startNode, endNode)); - - current = null; - } - - protected void visitChildren(Tile endNode) { - if(debug) Effects.effect(Fx.spawn, current.node.worldx(), current.node.worldy()); - - nodes(current.node, node -> { - float addCost = estimate(current.node, node); - - float nodeCost = current.costSoFar + addCost; - - float nodeHeuristic; - NodeRecord nodeRecord = getNodeRecord(node); - - if (nodeRecord.category == CLOSED) { // The node is closed - - // If we didn't find a shorter route, skip - if (nodeRecord.costSoFar <= nodeCost){ - return; - } - - // We can use the node's old cost values to calculate its heuristic - // without calling the possibly expensive heuristic function - nodeHeuristic = nodeRecord.getEstimatedTotalCost() - nodeRecord.costSoFar; - } else if (nodeRecord.category == OPEN) { // The node is open - - //If our route is no better, then skip - if (nodeRecord.costSoFar <= nodeCost){ - return; - } - - // Remove it from the open list (it will be re-added with the new cost) - openList.remove(nodeRecord); - - // We can use the node's old cost values to calculate its heuristic - // without calling the possibly expensive heuristic function - nodeHeuristic = nodeRecord.getEstimatedTotalCost() - nodeRecord.costSoFar; - } else { // the node is unvisited - - // We'll need to calculate the heuristic value using the function, - // since we don't have a node record with a previously calculated value - nodeHeuristic = estimate(node, endNode); - } - - // Update node record's cost and connection - nodeRecord.costSoFar = nodeCost; - nodeRecord.from = current.node; - - // Add it to the open list with the estimated total cost - addToOpenList(nodeRecord, nodeCost + nodeHeuristic); - }); - } - - protected void nodes(Tile current, Consumer cons){ - if(obstacle(current)) return; - for(GridPoint2 p : Geometry.d4){ - int wx = current.x + p.x, wy = current.y + p.y; - Tile n = Structs.inBounds(wx, wy, tiles) ? tiles[wx][wy] : null; - if(!obstacle(n)) cons.accept(n); - } - } - - protected boolean obstacle(Tile tile){ - return tile == null || (tile.solid() && end.target() != tile && tile.target() != end) || !tile.block().alwaysReplace; - } - - protected float estimate(Tile tile, Tile other){ - 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(); - while (current.from != null) { - outPath.add(current.node); - current = records[(indexOf(current.from))]; - } - outPath.add(startNode); - - // Reverse the path - outPath.reverse(); - } - - protected void addToOpenList(NodeRecord nodeRecord, float estimatedTotalCost) { - openList.add(nodeRecord, estimatedTotalCost); - nodeRecord.category = OPEN; - } - - protected NodeRecord getNodeRecord(Tile node) { - if(records[indexOf(node)] == null){ - NodeRecord record = new NodeRecord(); - record.node = node; - record.searchId = searchId; - records[indexOf(node)] = record; - return record; - }else{ - NodeRecord record = records[indexOf(node)]; - if(record.searchId != searchId){ - record.category = UNVISITED; - record.searchId = searchId; - } - return record; - } - } - - private int indexOf(Tile node){ - return node.packedPosition(); - } - - static class NodeRecord extends BinaryHeap.Node { - Tile node; - Tile from; - - float costSoFar; - byte category; - - int searchId; - - public NodeRecord() { - super(0); - } - - public float getEstimatedTotalCost() { - return getValue(); - } - } -} \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java index a6ff070ded..5a1b6133c8 100644 --- a/core/src/io/anuke/mindustry/net/Net.java +++ b/core/src/io/anuke/mindustry/net/Net.java @@ -26,8 +26,6 @@ import static io.anuke.mindustry.Vars.headless; import static io.anuke.mindustry.Vars.ui; public class Net{ - public static final Object packetPoolLock = new Object(); - private static boolean server; private static boolean active; private static boolean clientLoaded; @@ -239,16 +237,12 @@ public class Net{ if(clientLoaded || ((object instanceof Packet) && ((Packet) object).isImportant())){ if(clientListeners.get(object.getClass()) != null) clientListeners.get(object.getClass()).accept(object); - synchronized(packetPoolLock){ - Pooling.free(object); - } + Pooling.free(object); }else if(!((object instanceof Packet) && ((Packet) object).isUnimportant())){ packetQueue.add(object); Log.info("Queuing packet {0}", object); }else{ - synchronized(packetPoolLock){ - Pooling.free(object); - } + Pooling.free(object); } }else{ Log.err("Unhandled packet type: '{0}'!", object); @@ -263,9 +257,7 @@ public class Net{ if(serverListeners.get(object.getClass()) != null){ if(serverListeners.get(object.getClass()) != null) serverListeners.get(object.getClass()).accept(connection, object); - synchronized(packetPoolLock){ - Pooling.free(object); - } + Pooling.free(object); }else{ Log.err("Unhandled packet type: '{0}'!", object.getClass()); } diff --git a/core/src/io/anuke/mindustry/net/NetworkIO.java b/core/src/io/anuke/mindustry/net/NetworkIO.java index b0dbd8beeb..9ab41aa0cf 100644 --- a/core/src/io/anuke/mindustry/net/NetworkIO.java +++ b/core/src/io/anuke/mindustry/net/NetworkIO.java @@ -153,8 +153,6 @@ public class NetworkIO{ Player player = players[0]; - //TODO !! use map name as the network map in Maps, so getMap() isn't null. - try(DataInputStream stream = new DataInputStream(is)){ float timerTime = stream.readFloat(); long timestamp = stream.readLong(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/AdminsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/AdminsDialog.java index dbfd1273f6..46f533c286 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/AdminsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/AdminsDialog.java @@ -1,6 +1,5 @@ package io.anuke.mindustry.ui.dialogs; -import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.net.Administration.PlayerInfo; import io.anuke.ucore.scene.ui.ScrollPane; import io.anuke.ucore.scene.ui.layout.Table; @@ -43,12 +42,18 @@ public class AdminsDialog extends FloatingDialog{ res.addImageButton("icon-cancel", 14 * 3, () -> { ui.showConfirm("$text.confirm", "$text.confirmunadmin", () -> { netServer.admins.unAdminPlayer(info.id); + playerGroup.forEach(player -> { + if(player.uuid.equals(info.id)){ + player.isAdmin = false; + } + }); + /* for(Player player : playerGroup.all()){ if(player.con != null){ player.isAdmin = false; break; } - } + }*/ setup(); }); }).size(h).pad(-14f); diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java index 718b071751..2bd79e4a63 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java @@ -19,12 +19,14 @@ import io.anuke.ucore.scene.ui.Image; import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.util.Bundles; +import io.anuke.ucore.util.Timer; import static io.anuke.mindustry.Vars.*; public class PlayerListFragment extends Fragment{ private boolean visible = false; private Table content = new Table().marginRight(13f).marginLeft(13f); + private Timer timer = new Timer(); @Override public void build(Group parent){ @@ -36,7 +38,7 @@ public class PlayerListFragment extends Fragment{ return; } - if(visible && Timers.get("player-list-rebuild", 20)){ + if(visible && timer.get(20)){ rebuild(); content.pack(); content.act(Gdx.graphics.getDeltaTime()); @@ -48,8 +50,7 @@ public class PlayerListFragment extends Fragment{ cont.table("pane", pane -> { pane.label(() -> Bundles.format(playerGroup.size() == 1 ? "text.players.single" : "text.players", playerGroup.size())); pane.row(); - pane.pane("clear", content) - .grow().get().setScrollingDisabled(true, false); + pane.pane("clear", content).grow().get().setScrollingDisabled(true, false); pane.row(); pane.table("pane", menu -> { @@ -71,10 +72,10 @@ public class PlayerListFragment extends Fragment{ float h = 74f; - for(Player player : playerGroup.all()){ + playerGroup.forEach(player -> { NetConnection connection = gwt ? null : player.con; - if(connection == null && Net.server() && !player.isLocal) continue; + if(connection == null && Net.server() && !player.isLocal) return; Table button = new Table("button"); button.left(); @@ -139,7 +140,7 @@ public class PlayerListFragment extends Fragment{ content.add(button).padBottom(-6).width(350f).maxHeight(h + 14); content.row(); - } + }); content.marginBottom(5); } diff --git a/core/src/io/anuke/mindustry/world/Build.java b/core/src/io/anuke/mindustry/world/Build.java index 256ffc9798..6bf1762586 100644 --- a/core/src/io/anuke/mindustry/world/Build.java +++ b/core/src/io/anuke/mindustry/world/Build.java @@ -11,7 +11,6 @@ import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Recipe; import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity; import io.anuke.ucore.core.Events; -import io.anuke.ucore.entities.Entities; import io.anuke.ucore.util.Geometry; import static io.anuke.mindustry.Vars.*; @@ -113,30 +112,9 @@ public class Build{ return false; } - rect.setSize(type.size * tilesize, type.size * tilesize); - rect.setCenter(type.offset() + x * tilesize, type.offset() + y * tilesize); - - if(type.solid || type.solidifes){ - synchronized(Entities.entityLock){ - try{ - - rect.setSize(tilesize * type.size).setCenter(x * tilesize + type.offset(), y * tilesize + type.offset()); - boolean[] result = {false}; - - Units.getNearby(rect, e -> { - if(e == null) return; //not sure why this happens? - e.getHitbox(hitrect); - - if(rect.overlaps(hitrect) && !e.isFlying()){ - result[0] = true; - } - }); - - if(result[0]) return false; - }catch(Exception e){ - return false; - } - } + if((type.solid || type.solidifes) && + Units.anyEntities(rect.setSize(tilesize * type.size).setCenter(x * tilesize + type.offset(), y * tilesize + type.offset()))){ + return false; } //check for enemy cores diff --git a/core/src/io/anuke/mindustry/world/Edges.java b/core/src/io/anuke/mindustry/world/Edges.java index 8565b5a50d..3ccae39ba1 100644 --- a/core/src/io/anuke/mindustry/world/Edges.java +++ b/core/src/io/anuke/mindustry/world/Edges.java @@ -64,19 +64,15 @@ public class Edges{ return polygons[(int) (radius * 2) - 1]; } - public static synchronized GridPoint2[] getEdges(int size){ + public static GridPoint2[] getEdges(int size){ if(size < 0 || size > maxSize) throw new RuntimeException("Block size must be between 0 and " + maxSize); return edges[size - 1]; } - public static synchronized GridPoint2[] getInsideEdges(int size){ + public static GridPoint2[] getInsideEdges(int size){ if(size < 0 || size > maxSize) throw new RuntimeException("Block size must be between 0 and " + maxSize); return edgeInside[size - 1]; } - - public static synchronized int getEdgeAmount(int size){ - return getEdges(size).length; - } } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java index 9d2bfcf444..63a2680e43 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java @@ -198,7 +198,7 @@ public class Conveyor extends Block{ } @Override - public synchronized void update(Tile tile){ + public void update(Tile tile){ ConveyorEntity entity = tile.entity(); entity.minitem = 1f; @@ -274,7 +274,7 @@ public class Conveyor extends Block{ } @Override - public synchronized int removeStack(Tile tile, Item item, int amount){ + public int removeStack(Tile tile, Item item, int amount){ ConveyorEntity entity = tile.entity(); entity.noSleep(); int removed = 0; @@ -300,13 +300,13 @@ public class Conveyor extends Block{ } @Override - public synchronized int acceptStack(Item item, int amount, Tile tile, Unit source){ + public int acceptStack(Item item, int amount, Tile tile, Unit source){ ConveyorEntity entity = tile.entity(); return Math.min((int)(entity.minitem / itemSpace), amount); } @Override - public synchronized void handleStack(Item item, int amount, Tile tile, Unit source){ + public void handleStack(Item item, int amount, Tile tile, Unit source){ ConveyorEntity entity = tile.entity(); for(int i = amount - 1; i >= 0; i--){ diff --git a/kryonet/src/io/anuke/kryonet/ByteSerializer.java b/kryonet/src/io/anuke/kryonet/ByteSerializer.java index 55d8034913..c8155e458d 100644 --- a/kryonet/src/io/anuke/kryonet/ByteSerializer.java +++ b/kryonet/src/io/anuke/kryonet/ByteSerializer.java @@ -9,8 +9,6 @@ import io.anuke.ucore.util.Pooling; import java.nio.ByteBuffer; -import static io.anuke.mindustry.net.Net.packetPoolLock; - @SuppressWarnings("unchecked") public class ByteSerializer implements Serialization { @@ -36,11 +34,9 @@ public class ByteSerializer implements Serialization { if(id == -2){ return FrameworkSerializer.read(byteBuffer); }else{ - synchronized (packetPoolLock) { - Packet packet = Pooling.obtain((Class) Registrator.getByID(id).type, (Supplier) Registrator.getByID(id).constructor); - packet.read(byteBuffer); - return packet; - } + Packet packet = Pooling.obtain((Class) Registrator.getByID(id).type, (Supplier) Registrator.getByID(id).constructor); + packet.read(byteBuffer); + return packet; } } diff --git a/kryonet/src/io/anuke/kryonet/DefaultThreadImpl.java b/kryonet/src/io/anuke/kryonet/DefaultThreadImpl.java index ff2d80c4b2..9a50a4f51e 100644 --- a/kryonet/src/io/anuke/kryonet/DefaultThreadImpl.java +++ b/kryonet/src/io/anuke/kryonet/DefaultThreadImpl.java @@ -1,11 +1,27 @@ package io.anuke.kryonet; import io.anuke.mindustry.core.ThreadHandler.ThreadProvider; +import io.anuke.ucore.util.Threads; +import io.anuke.ucore.util.Threads.ThreadInfoProvider; import io.anuke.ucore.util.Log; -public class DefaultThreadImpl implements ThreadProvider { +public class DefaultThreadImpl implements ThreadProvider, ThreadInfoProvider{ private Thread thread; + public DefaultThreadImpl(){ + Threads.setThreadInfoProvider(this); + } + + @Override + public boolean isOnLogicThread(){ + return thread == null || isOnThread(); + } + + @Override + public boolean isOnGraphicsThread(){ + return thread == null || !isOnThread(); + } + @Override public boolean isOnThread() { return Thread.currentThread() == thread; diff --git a/kryonet/src/io/anuke/kryonet/KryoClient.java b/kryonet/src/io/anuke/kryonet/KryoClient.java index 1c42c67917..2719df75a4 100644 --- a/kryonet/src/io/anuke/kryonet/KryoClient.java +++ b/kryonet/src/io/anuke/kryonet/KryoClient.java @@ -23,7 +23,6 @@ import java.nio.ByteBuffer; import java.nio.channels.ClosedSelectorException; import static io.anuke.mindustry.Vars.*; -import static io.anuke.mindustry.net.Net.packetPoolLock; public class KryoClient implements ClientProvider{ Client client; @@ -159,9 +158,7 @@ public class KryoClient implements ClientProvider{ client.sendUDP(object); } - synchronized (packetPoolLock) { - Pooling.free(object); - } + Pooling.free(object); } @Override