diff --git a/annotations/build/libs/annotations-release.jar b/annotations/build/libs/annotations-release.jar index 3f5b430ca0..f6457dfeb4 100644 Binary files a/annotations/build/libs/annotations-release.jar and b/annotations/build/libs/annotations-release.jar differ diff --git a/annotations/src/io/anuke/annotations/AnnotationProcessor.java b/annotations/src/io/anuke/annotations/AnnotationProcessor.java index b38f7b34ab..f082ec1fb5 100644 --- a/annotations/src/io/anuke/annotations/AnnotationProcessor.java +++ b/annotations/src/io/anuke/annotations/AnnotationProcessor.java @@ -4,6 +4,7 @@ import com.squareup.javapoet.*; import io.anuke.annotations.Annotations.Local; import io.anuke.annotations.Annotations.RemoteClient; import io.anuke.annotations.Annotations.RemoteServer; +import io.anuke.annotations.Annotations.Unreliable; import javax.annotation.processing.*; import javax.lang.model.SourceVersion; @@ -22,7 +23,8 @@ import java.util.Set; @SupportedAnnotationTypes({ "io.anuke.annotations.Annotations.RemoteClient", "io.anuke.annotations.Annotations.RemoteServer", - "io.anuke.annotations.Annotations.Local" + "io.anuke.annotations.Annotations.Local", + "io.anuke.annotations.Annotations.Unreliable" }) public class AnnotationProcessor extends AbstractProcessor { private static final int maxPacketSize = 128; @@ -39,6 +41,19 @@ public class AnnotationProcessor extends AbstractProcessor { "rtype rvalue = io.anuke.mindustry.Vars.playerGroup.getByID(rbuffer.getInt())" } }); + + put("String", new String[][]{ + { + "rbuffer.putShort((short)rvalue.getBytes().length)", + "rbuffer.put(rvalue.getBytes())" + }, + { + "short __rvalue_length = rbuffer.getShort()", + "byte[] __rvalue_bytes = new byte[__rvalue_length]", + "rbuffer.get(__rvalue_bytes)", + "rtype rvalue = new rtype(__rvalue_bytes)" + } + }); }}; private Types typeUtils; @@ -109,6 +124,7 @@ public class AnnotationProcessor extends AbstractProcessor { if(e.getAnnotation(annotation) == null) continue; boolean local = e.getAnnotation(Local.class) != null; + boolean unreliable = e.getAnnotation(Unreliable.class) != null; ExecutableElement exec = (ExecutableElement)e; @@ -211,7 +227,8 @@ public class AnnotationProcessor extends AbstractProcessor { } } method.addStatement("packet.writeLength = TEMP_BUFFER.position()"); - method.addStatement("io.anuke.mindustry.net.Net.send(packet, io.anuke.mindustry.net.Net.SendMode.tcp)"); + method.addStatement("io.anuke.mindustry.net.Net.send(packet, "+ + (unreliable ? "io.anuke.mindustry.net.Net.SendMode.udp" : "io.anuke.mindustry.net.Net.SendMode.tcp")+")"); classBuilder.addMethod(method.build()); diff --git a/annotations/src/io/anuke/annotations/Annotations.java b/annotations/src/io/anuke/annotations/Annotations.java index 192b75b829..ec7931abd2 100644 --- a/annotations/src/io/anuke/annotations/Annotations.java +++ b/annotations/src/io/anuke/annotations/Annotations.java @@ -14,7 +14,8 @@ import java.lang.annotation.Target; * {@link RemoteServer}: Marks a method as able to be invoked remotely on a server from a client.
* {@link Local}: Makes this method get invoked locally as well as remotely.
*
- * All RemoteClient methods are put in the class CallClient, and all RemoteServer methods are put in the class CallServer.
+ * All RemoteClient methods are put in the class io.anuke.mindustry.gen.CallClient.
+ * All RemoteServer methods are put in the class io.anuke.mindustry.gen.CallServer.
*/ public class Annotations { @@ -35,4 +36,10 @@ public class Annotations { @Target(ElementType.METHOD) @Retention(RetentionPolicy.CLASS) public @interface Local{} + + /**Marks a method to be invoked unreliably, e.g. with UDP instead of TCP. + * This is faster, but is prone to packet loss and duplication.*/ + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.CLASS) + public @interface Unreliable{} } diff --git a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java index 36d4edb54b..1d008f8ba9 100644 --- a/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java +++ b/core/src/io/anuke/mindustry/content/blocks/PowerBlocks.java @@ -46,13 +46,11 @@ public class PowerBlocks { nuclearReactor = new NuclearReactor("nuclearreactor") {{ size = 3; health = 600; - breaktime *= 2.3f; }}, fusionReactor = new FusionReactor("fusionreactor") {{ size = 4; health = 600; - breaktime *= 4f; }}, repairturret = new RepairTurret("repairturret") {{ diff --git a/core/src/io/anuke/mindustry/core/ContentLoader.java b/core/src/io/anuke/mindustry/core/ContentLoader.java index f87664f130..8a3c24c6e1 100644 --- a/core/src/io/anuke/mindustry/core/ContentLoader.java +++ b/core/src/io/anuke/mindustry/core/ContentLoader.java @@ -60,7 +60,7 @@ public class ContentLoader { Log.info("--- CONTENT INFO ---"); Log.info("Blocks loaded: {0}\nItems loaded: {1}\nLiquids loaded: {2}\nUpgrades loaded: {3}\nUnits loaded: {4}\nAmmo types loaded: {5}\nStatus effects loaded: {6}\nRecipes loaded: {7}\nTotal content classes: {8}", Block.getAllBlocks().size, Item.getAllItems().size, Liquid.getAllLiquids().size, - Mech.getAllUpgrades().size, UnitType.getAllTypes().size, AmmoType.getAllTypes().size, StatusEffect.getAllEffects().size, Recipe.all().size, content.length); + Mech.getAllUpgrades().size, UnitType.getAllTypes().size, AmmoType.getAllTypes().size, StatusEffect.getAllEffects().size, Recipe.getAllRecipes().size, content.length); Log.info("-------------------"); } diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index a4a3b57193..5a17ad4c16 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -2,7 +2,10 @@ package io.anuke.mindustry.core; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; +import com.badlogic.gdx.audio.Sound; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.utils.ObjectMap; +import com.badlogic.gdx.utils.TimeUtils; import io.anuke.mindustry.content.Mechs; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.Player; @@ -20,7 +23,7 @@ import io.anuke.ucore.core.*; import io.anuke.ucore.entities.Entities; import io.anuke.ucore.input.InputProxy; import io.anuke.ucore.modules.Module; -import io.anuke.ucore.util.*; +import io.anuke.ucore.util.Atlas; import static io.anuke.mindustry.Vars.*; @@ -29,10 +32,14 @@ import static io.anuke.mindustry.Vars.*; * Should not handle any logic-critical state. * This class is not created in the headless server.*/ public class Control extends Module{ + /**Minimum period of time between the same sound being played.*/ + private static final long minSoundPeriod = 30; + private boolean hiscore = false; private boolean wasPaused = false; private Saves saves; private InputHandler[] inputs = {}; + private ObjectMap soundMap = new ObjectMap<>(); private Throwable error; private InputProxy proxy; @@ -85,6 +92,15 @@ public class Control extends Module{ "ping.mp3", "tesla.mp3", "waveend.mp3", "railgun.mp3", "blast.mp3", "bang2.mp3"); Sounds.setFalloff(9000f); + Sounds.setPlayer(((sound, volume) -> { + long time = TimeUtils.millis(); + long value = soundMap.get(sound, 0L); + + if(TimeUtils.timeSinceMillis(value) >= minSoundPeriod){ + threads.run(() -> sound.play(volume)); + soundMap.put(sound, time); + } + })); Musics.load("1.mp3", "2.mp3", "3.mp3", "4.mp3"); diff --git a/core/src/io/anuke/mindustry/core/GameState.java b/core/src/io/anuke/mindustry/core/GameState.java index 6d673462f9..4abc23acb4 100644 --- a/core/src/io/anuke/mindustry/core/GameState.java +++ b/core/src/io/anuke/mindustry/core/GameState.java @@ -3,15 +3,12 @@ package io.anuke.mindustry.core; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.EventType.StateChangeEvent; import io.anuke.mindustry.game.GameMode; -import io.anuke.mindustry.game.Inventory; import io.anuke.mindustry.game.TeamInfo; import io.anuke.ucore.core.Events; public class GameState{ private State state = State.menu; - public final Inventory inventory = new Inventory(); - public int wave = 1; public float wavetime; public float extrawavetime; diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index 1e11daf545..5bb0181d14 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -17,8 +17,6 @@ import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.modules.Module; -import java.sql.Time; - import static io.anuke.mindustry.Vars.*; /**Logic module. @@ -44,12 +42,6 @@ public class Logic extends Module { public void play(){ state.wavetime = wavespace * state.difficulty.timeScaling * 2; - if(state.mode.infiniteResources){ - state.inventory.fill(); - }else{ - state.inventory.clearItems(); - } - Events.fire(PlayEvent.class); } diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 94ef2dde1c..424c75e5be 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -3,7 +3,6 @@ package io.anuke.mindustry.core; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.utils.IntMap; import com.badlogic.gdx.utils.IntSet; -import io.anuke.mindustry.content.UpgradeRecipes; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.Player; @@ -17,7 +16,7 @@ import io.anuke.mindustry.net.Packets.*; import io.anuke.mindustry.resource.Recipe; import io.anuke.mindustry.resource.Upgrade; import io.anuke.mindustry.resource.Weapon; -import io.anuke.mindustry.world.Placement; +import io.anuke.mindustry.world.Build; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Timers; @@ -153,8 +152,6 @@ public class NetClient extends Module { }); Net.handleClient(StateSyncPacket.class, packet -> { - System.arraycopy(packet.items, 0, state.inventory.writeItems(), 0, packet.items.length); - state.enemies = packet.enemies; state.wavetime = packet.countdown; state.wave = packet.wave; @@ -178,7 +175,7 @@ public class NetClient extends Module { Net.handleClient(BreakPacket.class, (packet) -> { Player placer = playerGroup.getByID(packet.playerid); - Placement.breakBlock(placer.team, packet.x, packet.y, true, Timers.get("breakblocksound", 10)); + Build.breakBlock(placer.team, packet.x, packet.y, true, Timers.get("breakblocksound", 10)); }); Net.handleClient(EntitySpawnPacket.class, packet -> { @@ -271,7 +268,6 @@ public class NetClient extends Module { Net.handleClient(UpgradePacket.class, packet -> { Weapon weapon = Upgrade.getByID(packet.upgradeid); - state.inventory.removeItems(UpgradeRecipes.get(weapon)); for(Player player : players) { player.upgrades.add(weapon); } diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index f0ef99fa84..0a39b43a41 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -5,7 +5,6 @@ import com.badlogic.gdx.utils.IntMap; import com.badlogic.gdx.utils.TimeUtils; import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.Mechs; -import io.anuke.mindustry.content.UpgradeRecipes; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.Player; @@ -21,7 +20,7 @@ import io.anuke.mindustry.resource.Recipe; import io.anuke.mindustry.resource.Upgrade; import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.Placement; +import io.anuke.mindustry.world.Build; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.BaseBulletType; @@ -203,7 +202,7 @@ public class NetServer extends Module{ Recipe recipe = Recipe.getByID(packet.recipe); Block block = recipe.result; - if(!Placement.validPlace(placer.team, packet.x, packet.y, block, packet.rotation)) return; + if(!Build.validPlace(placer.team, packet.x, packet.y, block, packet.rotation)) return; if(recipe == null || recipe.debugOnly != debug) return; @@ -215,8 +214,6 @@ public class NetServer extends Module{ return; } - state.inventory.removeItems(recipe.requirements); - //todo implement placing //Placement.placeBlock(placer, packet.x, packet.y, recipe, packet.rotation, true, false); @@ -233,7 +230,7 @@ public class NetServer extends Module{ Player placer = connections.get(id); packet.playerid = placer.id; - if(!Placement.validBreak(placer.team, packet.x, packet.y)) return; + if(!Build.validBreak(placer.team, packet.x, packet.y)) return; Tile tile = world.tile(packet.x, packet.y); @@ -244,7 +241,7 @@ public class NetServer extends Module{ return; } - Block block = Placement.breakBlock(placer.team, packet.x, packet.y, true, false); + Block block = Build.breakBlock(placer.team, packet.x, packet.y, true, false); if(block != null) { TraceInfo trace = admins.getTraceByID(getUUID(id)); @@ -283,9 +280,7 @@ public class NetServer extends Module{ Weapon weapon = Upgrade.getByID(packet.upgradeid); - if(!state.inventory.hasItems(UpgradeRecipes.get(weapon))){ - return; - } + //todo verify upgrades with item requirements if (!player.upgrades.contains(weapon, true)){ player.upgrades.add(weapon); @@ -293,7 +288,6 @@ public class NetServer extends Module{ return; } - state.inventory.removeItems(UpgradeRecipes.get(weapon)); Net.send(packet, SendMode.tcp); }); @@ -493,7 +487,6 @@ public class NetServer extends Module{ if(timer.get(timerStateSync, itemSyncTime)){ StateSyncPacket packet = new StateSyncPacket(); - packet.items = state.inventory.readItems(); packet.countdown = state.wavetime; packet.enemies = state.enemies; packet.wave = state.wave; diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 67dfbfdb3a..224c61c90c 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -4,7 +4,6 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture.TextureWrap; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; @@ -12,7 +11,6 @@ import com.badlogic.gdx.utils.FloatArray; import com.badlogic.gdx.utils.Pools; import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.BlockPlacer.PlaceRequest; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.effect.BelowLiquidEffect; @@ -22,14 +20,16 @@ import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.graphics.*; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.Placement; import io.anuke.ucore.core.*; import io.anuke.ucore.entities.EffectEntity; import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entity; import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.function.Callable; -import io.anuke.ucore.graphics.*; +import io.anuke.ucore.graphics.Draw; +import io.anuke.ucore.graphics.Hue; +import io.anuke.ucore.graphics.Lines; +import io.anuke.ucore.graphics.Surface; import io.anuke.ucore.modules.RendererModule; import io.anuke.ucore.scene.utils.Cursors; import io.anuke.ucore.util.Mathf; @@ -206,13 +206,11 @@ public class Renderer extends RendererModule{ blocks.processBlocks(); blocks.drawBlocks(Layer.block); - //Graphics.surface(effectSurface, true); Graphics.shader(Shaders.blockbuild, false); blocks.drawBlocks(Layer.placement); Graphics.shader(); - //Graphics.flushSurface(); - drawPlaceRequests(); + Entities.drawWith(playerGroup, p -> true, Player::drawBuildRequests); blocks.drawBlocks(Layer.overlay); @@ -227,35 +225,18 @@ public class Renderer extends RendererModule{ Entities.draw(airItemGroup); Entities.draw(effectGroup); - //drawShield(); - overlays.draw(); if(pixelate) Graphics.flushSurface(); if(showPaths) drawDebug(); - drawPlayerNames(); + + Entities.drawWith(playerGroup, p -> !p.isLocal && !p.isDead(), Player::drawName); batch.end(); } - private void drawPlaceRequests(){ - Draw.color("accent"); - - for(Player player : playerGroup.all()) { - for (PlaceRequest request : player.getPlaceQueue()) { - if(Placement.validPlace(player.team, request.x, request.y, request.recipe.result, request.rotation)){ - Lines.poly(request.x * tilesize + request.recipe.result.getPlaceOffset().x, - request.y * tilesize + request.recipe.result.getPlaceOffset().y, - 4, request.recipe.result.size * tilesize /2f + Mathf.absin(Timers.time(), 3f, 1f)); - } - } - } - - Draw.color(); - } - private void drawAllTeams(boolean flying){ for(Team team : Team.values()){ EntityGroup group = unitGroups[team.ordinal()]; @@ -351,31 +332,6 @@ public class Renderer extends RendererModule{ Draw.color(); } - void drawPlayerNames(){ - GlyphLayout layout = Pools.obtain(GlyphLayout.class); - - Draw.tscl(0.25f/2); - for(Player player : playerGroup.all()){ - if(!player.isLocal && !player.isDead()){ - layout.setText(Core.font, player.name); - Draw.color(0f, 0f, 0f, 0.3f); - Draw.rect("blank", player.getDrawPosition().x, player.getDrawPosition().y + 8 - layout.height/2, layout.width + 2, layout.height + 2); - Draw.color(); - Draw.tcolor(player.getColor()); - Draw.text(player.name, player.getDrawPosition().x, player.getDrawPosition().y + 8); - - if(player.isAdmin){ - Draw.color(player.getColor()); - float s = 3f; - Draw.rect("icon-admin-small", player.getDrawPosition().x + layout.width/2f + 2 + 1, player.getDrawPosition().y + 7f, s, s); - } - Draw.reset(); - } - } - Pools.free(layout); - Draw.tscl(fontscale); - } - void drawShield(){ if(shieldGroup.size() == 0 && shieldDraws.size == 0) return; diff --git a/core/src/io/anuke/mindustry/entities/BlockBuilder.java b/core/src/io/anuke/mindustry/entities/BlockBuilder.java new file mode 100644 index 0000000000..dfb9f58714 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/BlockBuilder.java @@ -0,0 +1,154 @@ +package io.anuke.mindustry.entities; + +import com.badlogic.gdx.utils.Queue; +import io.anuke.mindustry.Vars; +import io.anuke.mindustry.resource.Recipe; +import io.anuke.mindustry.world.Build; +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.types.BuildBlock; +import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity; +import io.anuke.ucore.core.Timers; +import io.anuke.ucore.graphics.Draw; +import io.anuke.ucore.graphics.Fill; +import io.anuke.ucore.graphics.Lines; +import io.anuke.ucore.util.Angles; +import io.anuke.ucore.util.Geometry; +import io.anuke.ucore.util.Mathf; +import io.anuke.ucore.util.Translator; + +import java.util.Arrays; + +import static io.anuke.mindustry.Vars.world; + +/**Interface for units that build thing.*/ +public interface BlockBuilder { + //temporary static final values + Translator[] tmptr = {new Translator(), new Translator(), new Translator(), new Translator()}; + float placeDistance = 80f; + + /**Returns the queue for storing build requests.*/ + Queue getPlaceQueue(); + + /**Clears the placement queue.*/ + default void clearBuilding(){ + getPlaceQueue().clear(); + } + + /**Add another build requests to the tail of the queue.*/ + default void addBuildRequest(BuildRequest place){ + getPlaceQueue().addLast(place); + } + + /**Return the build requests currently active, or the one at the top of the queue. + * May return null.*/ + default BuildRequest getCurrentRequest(){ + return getPlaceQueue().size == 0 ? null : getPlaceQueue().first(); + } + + /**Update building mechanism for this unit.*/ + default void updateBuilding(Unit unit){ + BuildRequest current = getCurrentRequest(); + + if(current == null) return; //nothing to do here + + Tile tile = world.tile(current.x, current.y); + + if(unit.distanceTo(tile) > placeDistance) { //out of range, skip it. + getPlaceQueue().removeFirst(); + }else if(current.remove){ + if(Build.validBreak(unit.team, current.x, current.y)){ //if it's valid, break it + current.removeProgress += 1f / tile.getBreakTime(); + + if(current.removeProgress >= 1f){ + Build.breakBlock(unit.team, current.x, current.y, true, true); + } + }else{ + //otherwise, skip it + getPlaceQueue().removeFirst(); + } + }else{ + if (!(tile.block() instanceof BuildBlock)) { //check if haven't started placing + if(Build.validPlace(unit.team, current.x, current.y, current.recipe.result, current.rotation)){ + //if it's valid, place it + Build.placeBlock(unit.team, current.x, current.y, current.recipe, current.rotation); + }else{ + //otherwise, skip it + getPlaceQueue().removeFirst(); + } + }else{ + //otherwise, update it. + BuildEntity entity = tile.entity(); + + entity.progress += 1f / entity.recipe.cost; + unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f); + } + } + } + + /**Draw placement effects for an entity.*/ + default void drawBuilding(Unit unit){ + Tile tile = world.tile(getCurrentRequest().x, getCurrentRequest().y); + + Draw.color(unit.distanceTo(tile) > placeDistance ? "placeInvalid" : "accent"); + float focusLen = 3.8f + Mathf.absin(Timers.time(), 1.1f, 0.6f); + float px = unit.x + Angles.trnsx(unit.rotation, focusLen); + float py = unit.y + Angles.trnsy(unit.rotation, focusLen); + + float sz = Vars.tilesize*tile.block().size/2f; + float ang = unit.angleTo(tile); + + tmptr[0].set(tile.drawx() - sz, tile.drawy() - sz); + tmptr[1].set(tile.drawx() + sz, tile.drawy() - sz); + tmptr[2].set(tile.drawx() - sz, tile.drawy() + sz); + tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz); + + Arrays.sort(tmptr, (a, b) -> -Float.compare(Angles.angleDist(Angles.angle(unit.x, unit.y, a.x, a.y), ang), + Angles.angleDist(Angles.angle(unit.x, unit.y, b.x, b.y), ang))); + + float x1 = tmptr[0].x, y1 = tmptr[0].y, + x3 = tmptr[1].x, y3 = tmptr[1].y; + Translator close = Geometry.findClosest(unit.x, unit.y, tmptr); + float x2 = close.x, y2 = close.y; + + Draw.alpha(0.3f + Mathf.absin(Timers.time(), 0.9f, 0.2f)); + + Fill.tri(px, py, x2, y2, x1, y1); + Fill.tri(px, py, x2, y2, x3, y3); + + Draw.alpha(1f); + + Lines.line(px, py, x1, y1); + Lines.line(px, py, x3, y3); + + Fill.circle(px, py, 1.5f + Mathf.absin(Timers.time(), 1f, 1.8f)); + + Draw.color(); + } + + /**Class for storing build requests. Can be either a place or remove request.*/ + class BuildRequest { + public final int x, y, rotation; + public final Recipe recipe; + public final boolean remove; + + float removeProgress; + + /**This creates a build request.*/ + public BuildRequest(int x, int y, int rotation, Recipe recipe) { + this.x = x; + this.y = y; + this.rotation = rotation; + this.recipe = recipe; + this.remove = false; + } + + /**This creates a remove request.*/ + public BuildRequest(int x, int y) { + this.x = x; + this.y = y; + this.rotation = -1; + this.recipe = null; + this.remove = true; + } + } +} diff --git a/core/src/io/anuke/mindustry/entities/BlockPlacer.java b/core/src/io/anuke/mindustry/entities/BlockPlacer.java deleted file mode 100644 index e490fc9c38..0000000000 --- a/core/src/io/anuke/mindustry/entities/BlockPlacer.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.anuke.mindustry.entities; - -import io.anuke.mindustry.game.Team; -import io.anuke.mindustry.resource.Recipe; - -public interface BlockPlacer { - void addPlaceBlock(PlaceRequest place); - Team getTeam(); - - class PlaceRequest{ - public final int x, y, rotation; - public final Recipe recipe; - - public PlaceRequest(int x, int y, int rotation, Recipe recipe) { - this.x = x; - this.y = y; - this.rotation = rotation; - this.recipe = recipe; - } - } -} diff --git a/core/src/io/anuke/mindustry/entities/ItemAnimationEffect.java b/core/src/io/anuke/mindustry/entities/ItemAnimationEffect.java index 34f3cbac9d..fded944215 100644 --- a/core/src/io/anuke/mindustry/entities/ItemAnimationEffect.java +++ b/core/src/io/anuke/mindustry/entities/ItemAnimationEffect.java @@ -10,6 +10,8 @@ import io.anuke.ucore.function.Callable; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; +/**This class should not be used anymore, as the animation does not fit the style well.*/ +@Deprecated public class ItemAnimationEffect extends TimedEntity { private static final float size = 5f; diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index 6f8c147d6f..f04edbebf1 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -1,10 +1,11 @@ package io.anuke.mindustry.entities; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.Pools; import com.badlogic.gdx.utils.Queue; -import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.Mechs; import io.anuke.mindustry.content.Weapons; import io.anuke.mindustry.content.fx.ExplosionFx; @@ -14,18 +15,11 @@ import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.NetEvents; import io.anuke.mindustry.resource.*; -import io.anuke.mindustry.world.Placement; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.types.BuildBlock; -import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity; import io.anuke.mindustry.world.blocks.types.Floor; -import io.anuke.ucore.core.Effects; -import io.anuke.ucore.core.Inputs; -import io.anuke.ucore.core.Settings; -import io.anuke.ucore.core.Timers; +import io.anuke.ucore.core.*; import io.anuke.ucore.entities.SolidEntity; import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.graphics.Fill; import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.util.*; @@ -33,17 +27,13 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.ByteBuffer; -import java.util.Arrays; import static io.anuke.mindustry.Vars.*; -public class Player extends Unit implements BlockPlacer{ - static final float speed = 1.1f; - static final float dashSpeed = 1.8f; - public static final float placeDistance = 80f; - - static final int timerRegen = 3; - static final Translator[] tmptr = {new Translator(), new Translator(), new Translator(), new Translator()}; +public class Player extends Unit implements BlockBuilder { + private static final float speed = 1.1f; + private static final float dashSpeed = 1.8f; + private static final Vector2 movement = new Vector2(); public String name = "name"; public String uuid; @@ -61,12 +51,10 @@ public class Player extends Unit implements BlockPlacer{ public int playerIndex = 0; public boolean isLocal = false; public Timer timer = new Timer(4); - public float walktime; - public float respawntime; - private Queue placeQueue = new Queue<>(); - private Tile currentPlace; - private Vector2 movement = new Vector2(); + private float walktime; + private float respawntime; + private Queue placeQueue = new Queue<>(); public Player(){ hitbox.setSize(5); @@ -110,11 +98,6 @@ public class Player extends Unit implements BlockPlacer{ } } - @Override - public void addPlaceBlock(PlaceRequest req){ - placeQueue.addFirst(req); - } - @Override public boolean collides(SolidEntity other){ return !isDead() && super.collides(other) && !mech.flying; @@ -227,45 +210,49 @@ public class Player extends Unit implements BlockPlacer{ @Override public void drawOver(){ - if(!isShooting() && currentPlace != null) { - Draw.color(distanceTo(currentPlace) > placeDistance ? "placeInvalid" : "accent"); - float focusLen = 3.8f + Mathf.absin(Timers.time(), 1.1f, 0.6f); - float px = x + Angles.trnsx(rotation, focusLen); - float py = y + Angles.trnsy(rotation, focusLen); - - Tile tile = currentPlace; - - float sz = Vars.tilesize*tile.block().size/2f; - float ang = angleTo(tile); - - tmptr[0].set(tile.drawx() - sz, tile.drawy() - sz); - tmptr[1].set(tile.drawx() + sz, tile.drawy() - sz); - tmptr[2].set(tile.drawx() - sz, tile.drawy() + sz); - tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz); - - Arrays.sort(tmptr, (a, b) -> -Float.compare(Angles.angleDist(Angles.angle(x, y, a.x, a.y), ang), - Angles.angleDist(Angles.angle(x, y, b.x, b.y), ang))); - - float x1 = tmptr[0].x, y1 = tmptr[0].y, - x3 = tmptr[1].x, y3 = tmptr[1].y; - Translator close = Geometry.findClosest(x, y, tmptr); - float x2 = close.x, y2 = close.y; - - Draw.alpha(0.3f + Mathf.absin(Timers.time(), 0.9f, 0.2f)); - - Fill.tri(px, py, x2, y2, x1, y1); - Fill.tri(px, py, x2, y2, x3, y3); - - Draw.alpha(1f); - - Lines.line(px, py, x1, y1); - Lines.line(px, py, x3, y3); - - Fill.circle(px, py, 1.5f + Mathf.absin(Timers.time(), 1f, 1.8f)); - - Draw.color(); + if(!isShooting() && getCurrentRequest() != null) { + drawBuilding(this); } } + + public void drawName(){ + GlyphLayout layout = Pools.obtain(GlyphLayout.class); + + Draw.tscl(0.25f/2); + layout.setText(Core.font, name); + Draw.color(0f, 0f, 0f, 0.3f); + Draw.rect("blank", getDrawPosition().x, getDrawPosition().y + 8 - layout.height/2, layout.width + 2, layout.height + 2); + Draw.color(); + Draw.tcolor(color); + Draw.text(name, getDrawPosition().x, getDrawPosition().y + 8); + + if(isAdmin){ + Draw.color(color); + float s = 3f; + Draw.rect("icon-admin-small", getDrawPosition().x + layout.width/2f + 2 + 1, getDrawPosition().y + 7f, s, s); + } + + Draw.reset(); + Pools.free(layout); + Draw.tscl(fontscale); + } + + public void drawBuildRequests(){ + for (BuildRequest request : getPlaceQueue()) { + if(request.remove){ + Draw.color("placeInvalid"); + Tile tile = world.tile(request.x, request.y); + + Lines.poly(tile.drawx(), tile.drawy(), + 4, tile.block().size * tilesize /2f + Mathf.absin(Timers.time(), 3f, 1f)); + }else{ + Draw.color("accent"); + Lines.poly(request.x * tilesize + request.recipe.result.getPlaceOffset().x, + request.y * tilesize + request.recipe.result.getPlaceOffset().y, + 4, request.recipe.result.size * tilesize /2f + Mathf.absin(Timers.time(), 3f, 1f)); + } + } + } @Override public void update(){ @@ -300,6 +287,7 @@ public class Player extends Unit implements BlockPlacer{ y = Mathf.clamp(y, 0, world.height() * tilesize); } + /**Resets all values of the player.*/ public void reset(){ weapon = Weapons.blaster; team = Team.blue; @@ -316,12 +304,11 @@ public class Player extends Unit implements BlockPlacer{ return control.input(playerIndex).canShoot() && control.input(playerIndex).isShooting() && inventory.hasAmmo(); } - public Queue getPlaceQueue(){ + public Queue getPlaceQueue(){ return placeQueue; } protected void updateMech(){ - Tile tile = world.tileWorld(x, y); //if player is in solid block @@ -330,29 +317,7 @@ public class Player extends Unit implements BlockPlacer{ } if(!isShooting()) { - //update placing queue - - if(currentPlace != null) { - Tile check = currentPlace; - - if (!(check.block() instanceof BuildBlock)) { - currentPlace = null; - }else if(distanceTo(check) <= placeDistance){ - BuildEntity entity = check.entity(); - - entity.progress += 1f / entity.recipe.cost; - rotation = Mathf.slerpDelta(rotation, angleTo(entity), 0.4f); - } - - }else if(placeQueue.size > 0){ - PlaceRequest check = placeQueue.last(); - if(distanceTo(world.tile(check.x, check.y)) <= placeDistance && - Placement.validPlace(team, check.x, check.y, check.recipe.result, check.rotation)){ - placeQueue.removeLast(); - Placement.placeBlock(team, check.x, check.y, check.recipe, check.rotation, true, true); - currentPlace = world.tile(check.x, check.y); - } - } + updateBuilding(this); } if(ui.chatfrag.chatOpen()) return; @@ -365,11 +330,6 @@ public class Player extends Unit implements BlockPlacer{ speed *= ((1f-carrySlowdown) + (inventory.hasItem() ? (float)inventory.getItem().amount/inventory.capacity(): 1f) * carrySlowdown); - if(health < maxhealth && timer.get(timerRegen, 20)) - health ++; - - health = Mathf.clamp(health, -1, maxhealth); - movement.set(0, 0); String section = "player_" + (playerIndex + 1); @@ -524,18 +484,4 @@ public class Player extends Unit implements BlockPlacer{ interpolator.read(this.x, this.y, x, y, rot, baseRot, time); } - - @Override - public void interpolate() { - super.interpolate(); - - Interpolator i = interpolator; - - float tx = x + Angles.trnsx(rotation + 180f, 4f); - float ty = y + Angles.trnsy(rotation + 180f, 4f); - } - - public Color getColor(){ - return color; - } } diff --git a/core/src/io/anuke/mindustry/entities/Predict.java b/core/src/io/anuke/mindustry/entities/Predict.java index a39eced4da..88dfd8957b 100644 --- a/core/src/io/anuke/mindustry/entities/Predict.java +++ b/core/src/io/anuke/mindustry/entities/Predict.java @@ -3,12 +3,13 @@ package io.anuke.mindustry.entities; import com.badlogic.gdx.math.Vector2; import io.anuke.ucore.util.Mathf; +/**Class for predicting shoot angles based on velocities of targets.*/ public class Predict { private static Vector2 vec = new Vector2(); private static Vector2 vresult = new Vector2(); /**Returns resulting predicted vector. - * Don't call from multiple threads, ever.*/ + * Don't call from multiple threads.*/ public static Vector2 intercept(float srcx, float srcy, float dstx, float dsty, float dstvx, float dstvy, float v) { float tx = dstx - srcx, ty = dsty - srcy, @@ -37,7 +38,6 @@ public class Predict { return sol; } - private static Vector2 quad(float a, float b, float c) { Vector2 sol = null; if (Math.abs(a) < 1e-6) { diff --git a/core/src/io/anuke/mindustry/entities/StatusController.java b/core/src/io/anuke/mindustry/entities/StatusController.java index 57cecdd232..b6bcba7aef 100644 --- a/core/src/io/anuke/mindustry/entities/StatusController.java +++ b/core/src/io/anuke/mindustry/entities/StatusController.java @@ -3,6 +3,7 @@ package io.anuke.mindustry.entities; import io.anuke.mindustry.content.StatusEffects; import io.anuke.ucore.core.Timers; +/**Class for controlling status effects on an entity.*/ public class StatusController { private static final TransitionResult globalResult = new TransitionResult(); diff --git a/core/src/io/anuke/mindustry/game/Tutorial.java b/core/src/io/anuke/mindustry/game/Tutorial.java deleted file mode 100644 index 537afad744..0000000000 --- a/core/src/io/anuke/mindustry/game/Tutorial.java +++ /dev/null @@ -1,578 +0,0 @@ -package io.anuke.mindustry.game; - -import com.badlogic.gdx.math.GridPoint2; -import io.anuke.mindustry.content.Items; -import io.anuke.mindustry.content.blocks.Blocks; -import io.anuke.mindustry.content.blocks.DistributionBlocks; -import io.anuke.mindustry.content.blocks.WeaponBlocks; -import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.world.Block; -import io.anuke.ucore.core.Timers; -import io.anuke.ucore.scene.builders.button; -import io.anuke.ucore.scene.builders.label; -import io.anuke.ucore.scene.builders.table; -import io.anuke.ucore.scene.ui.ImageButton; -import io.anuke.ucore.scene.ui.Label; -import io.anuke.ucore.scene.ui.TextButton; -import io.anuke.ucore.util.Bundles; -import io.anuke.ucore.util.Tmp; - -import static io.anuke.mindustry.Vars.*; - -public class Tutorial{ - private Stage stage; - private Label info; - private TextButton next, prev; - - public Tutorial(){ - reset(); - } - - public boolean active(){ - return world.getMap() != null && world.getMap().name.equals("tutorial") && !state.is(State.menu); - } - - public void buildUI(table table){ - - table.atop(); - - new table("pane"){{ - atop(); - margin(12); - - info = new label(()->stage.text).pad(10f).padBottom(5f).width(340f).colspan(2).get(); - info.setWrap(true); - - row(); - - prev = new button("$text.tutorial.back", ()->{ - if(!prev.isDisabled()) - move(false); - }).left().get(); - - next = new button("$text.tutorial.next", ()->{ - if(!next.isDisabled()) - move(true); - }).right().get(); - - - }}.end(); - - prev.margin(16); - next.margin(16); - - prev.setDisabled(()->!canMove(false) || !stage.canBack); - next.setDisabled(()->!stage.canForward); - } - - public void update(){ - stage.update(this); - //info.setText(stage.text); - - if(stage.showBlock){ - /* - Tile tile = world.tile(world.getCore().x + stage.blockPlaceX, world.getCore().y + stage.blockPlaceY); - - if(tile.block() == stage.targetBlock && (tile.getRotation() == stage.blockRotation || stage.blockRotation == -1)){ - move(true); - }*/ - } - } - - public void reset(){ - stage = Stage.values()[0]; - stage.onSwitch(); - } - - public void complete(){ - //new TextDialog("Congratulations!", "You have completed the tutorial!").padText(Unit.dp.inPixels(10f)).show(); - state.set(State.menu); - reset(); - } - - void move(boolean forward){ - //TODO - } - - boolean canMove(boolean forward){ - return true; - - } - - public boolean showTarget(){ - return stage == Stage.shoot; - } - - public boolean canPlace(){ - return stage.canPlace; - } - - public boolean showBlock(){ - return stage.showBlock; - } - - public Block getPlaceBlock(){ - return stage.targetBlock; - } - - public GridPoint2 getPlacePoint(){ - return Tmp.g1.set(stage.blockPlaceX, stage.blockPlaceY); - } - - public int getPlaceRotation(){ - return stage.blockRotation; - } - - public void setDefaultBlocks(int corex, int corey){ - world.tile(corex, corey - 2).setBlock(Blocks.air); - world.tile(corex, corey - 3).setBlock(Blocks.air); - world.tile(corex, corey - 3).setFloor(Blocks.stone); - - world.tile(corex + 1, corey - 8).setFloor(Blocks.iron); - world.tile(corex - 1, corey - 8).setFloor(Blocks.coal); - - int r = 10; - - for(int x = -r; x <= r; x ++){ - for(int y = -r; y <= r; y ++){ - if(world.tile(corex + x, corey + y).block() == Blocks.rock){ - world.tile(corex + x, corey + y).setBlock(Blocks.air); - } - } - } - } - - public enum Stage{ - intro{ - { - } - }, - moveDesktop{ - { - desktopOnly = true; - } - }, - shoot{ - { - desktopOnly = true; - } - }, - moveAndroid{ - { - androidOnly = true; - } - }, - placeSelect{ - { - canBack = false; - canPlace = true; - } - - void onSwitch(){ - ui.find("sectionbuttondistribution").fireClick(); - } - }, - placeConveyorDesktop{ - { - desktopOnly = true; - canPlace = true; - showBlock = true; - canForward = false; - blockRotation = 1; - blockPlaceX = 0; - blockPlaceY = -2; - targetBlock = DistributionBlocks.conveyor; - } - }, - placeConveyorAndroid{ - { - androidOnly = true; - canPlace = true; - showBlock = true; - canForward = false; - blockRotation = 1; - blockPlaceX = 0; - blockPlaceY = -2; - targetBlock = DistributionBlocks.conveyor; - } - }, - placeConveyorAndroidInfo{ - { - androidOnly = true; - canBack = false; - } - - void onSwitch(){ - //player.recipe = null; - } - }, - placeDrill{ - { - canPlace = true; - canBack = false; - showBlock = true; - canForward = false; - blockPlaceX = 0; - blockPlaceY = -3; - //targetBlock = ProductionBlocks.stonedrill; - } - - void onSwitch(){ - ui.find("sectionbuttonproduction").fireClick(); - } - }, - blockInfo{ - { - canBack = true; - } - }, - deselectDesktop{ - { - desktopOnly = true; - canBack = false; - } - }, - deselectAndroid{ - { - androidOnly = true; - canBack = false; - } - }, - drillPlaced{ - { - canBack = false; - } - - void onSwitch(){ - } - }, - drillInfo{ - { - } - }, - drillPlaced2{ - { - } - }, - moreDrills{ - { - canBack = false; - } - - void onSwitch(){ - /* - for(int flip : new int[]{1, -1}){ - world.tile(world.getCore().x + flip, world.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip); - world.tile(world.getCore().x + flip*2, world.getCore().y - 2).setBlock(DistributionBlocks.conveyor, 2 * flip); - world.tile(world.getCore().x + flip*2, world.getCore().y - 3).setBlock(DistributionBlocks.conveyor, 2 * flip); - world.tile(world.getCore().x + flip*2, world.getCore().y - 3).setBlock(DistributionBlocks.conveyor, 1); - world.tile(world.getCore().x + flip*2, world.getCore().y - 4).setFloor(Blocks.stone); - world.tile(world.getCore().x + flip*2, world.getCore().y - 4).setBlock(ProductionBlocks.stonedrill); - - }*/ - } - }, - deleteBlock{ - { - canBack = false; - canForward = false; - showBlock = true; - targetBlock = Blocks.air; - blockPlaceX = 2; - blockPlaceY = -2; - desktopOnly = true; - } - }, - deleteBlockAndroid{ - { - canBack = false; - canForward = false; - showBlock = true; - targetBlock = Blocks.air; - blockPlaceX = 2; - blockPlaceY = -2; - androidOnly = true; - } - }, - placeTurret{ - { - canBack = false; - canForward = false; - showBlock = true; - canPlace = true; - targetBlock = WeaponBlocks.doubleturret; - blockPlaceX = 2; - blockPlaceY = 2; - } - - void onSwitch(){ - ui.find("sectionbuttonweapon").fireClick(); - } - }, - placedTurretAmmo{ - { - canBack = false; - } - - void onSwitch(){ - for(int i = 0; i < 4; i ++){ - //world.tile(world.getCore().x + 2, world.getCore().y - 2 + i).setBlock(DistributionBlocks.conveyor, 1); - } - - } - }, - turretExplanation{ - { - canBack = false; - } - }, - waves{ - { - } - }, - coreDestruction{ - { - } - }, - pausingDesktop{ - { - desktopOnly = true; - } - }, - pausingAndroid{ - { - androidOnly = true; - } - }, - //TODO re-add tutorial on weapons - - spawnWave{ - float warmup = 0f; - { - canBack = false; - canForward = false; - } - - void update(Tutorial t){ - warmup += Timers.delta(); - if(state.enemies == 0 && warmup > 60f){ - t.move(true); - } - } - - void onSwitch(){ - warmup = 0f; - logic.runWave(); - } - }, - pumpDesc{ - { - canBack = false; - } - }, - pumpPlace{ - { - canBack = false; - canForward = false; - showBlock = true; - canPlace = true; - //targetBlock = ProductionBlocks.pump; - blockPlaceX = 6; - blockPlaceY = -2; - } - - void onSwitch(){ - ui.find("sectionbuttonproduction").fireClick(); - state.inventory.addItem(Items.steel, 60); - state.inventory.addItem(Items.iron, 60); - } - }, - conduitUse{ - { - canBack = false; - canForward = false; - showBlock = true; - canPlace = true; - //targetBlock = DistributionBlocks.conduit; - blockPlaceX = 5; - blockPlaceY = -2; - blockRotation = 2; - } - - void onSwitch(){ - ui.find("sectionbuttondistribution").fireClick(); - //world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); - } - }, - conduitUse2{ - { - canBack = false; - canForward = false; - showBlock = true; - canPlace = true; - //targetBlock = DistributionBlocks.conduit; - //blockPlaceX = 4; - blockPlaceY = -2; - blockRotation = 1; - } - - void onSwitch(){ - //world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); - } - }, - conduitUse3{ - { - canBack = false; - canForward = false; - showBlock = true; - canPlace = true; - //targetBlock = DistributionBlocks.conduit; - blockPlaceX = 4; - blockPlaceY = -1; - blockRotation = 1; - } - - void onSwitch(){ - //world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); - } - }, - generator{ - { - canBack = false; - canForward = false; - showBlock = true; - canPlace = true; - //targetBlock = ProductionBlocks.combustiongenerator; - blockPlaceX = 4; - blockPlaceY = 0; - } - - void onSwitch(){ - //world.tile(blockPlaceX + world.getCore().x, blockPlaceY + world.getCore().y).setBlock(Blocks.air); - ui.find("sectionbuttonpower").fireClick(); - state.inventory.addItem(Items.steel, 60); - state.inventory.addItem(Items.iron, 60); - } - }, - generatorExplain{ - { - canBack = false; - } - }, - lasers{ - { - canBack = false; - canForward = false; - showBlock = true; - canPlace = true; - blockPlaceX = 4; - blockPlaceY = 4; - blockRotation = 2; - //targetBlock = DistributionBlocks.powerlaser; - } - - void onSwitch(){ - ui.find("sectionbuttonpower").fireClick(); - } - }, - laserExplain{ - { - canBack = false; - } - }, - laserMore{ - { - canBack = false; - } - }, - healingTurret{ - { - canBack = false; - canForward = false; - showBlock = true; - canPlace = true; - canBack = false; - blockPlaceX = 1; - blockPlaceY = 4; - //targetBlock = DefenseBlocks.repairturret; - } - - void onSwitch(){ - ui.find("sectionbuttonpower").fireClick(); - } - }, - healingTurretExplain{ - { - canBack = false; - } - }, - smeltery{ - { - canBack = false; - canForward = false; - showBlock = true; - canPlace = true; - canBack = false; - blockPlaceX = 0; - blockPlaceY = -7; - //targetBlock = ProductionBlocks.smelter; - } - - void onSwitch(){ - state.inventory.addItem(Items.stone, 40); - state.inventory.addItem(Items.iron, 40); - ui.find("sectionbuttoncrafting").fireClick(); - - } - }, - smelterySetup{ - { - canBack = false; - } - - void onSwitch(){ - /* - for(int i = 0; i < 5; i ++){ - world.tile(world.getCore().x, world.getCore().y - 6 + i).setBlock(DistributionBlocks.conveyor, 1); - } - - world.tile(world.getCore().x, world.getCore().y - 6 + 1).setBlock(DistributionBlocks.tunnel, 3); - world.tile(world.getCore().x, world.getCore().y - 6 + 2).setBlock(DefenseBlocks.stonewall, 0); - world.tile(world.getCore().x, world.getCore().y - 6 + 3).setBlock(DistributionBlocks.tunnel, 1); - - world.tile(world.getCore().x+1, world.getCore().y - 8).setBlock(ProductionBlocks.irondrill); - world.tile(world.getCore().x-1, world.getCore().y - 8).setBlock(ProductionBlocks.coaldrill); - - world.tile(world.getCore().x+1, world.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 2); - world.tile(world.getCore().x-1, world.getCore().y - 7).setBlock(DistributionBlocks.conveyor, 0);*/ - } - }, - tunnelExplain{ - { - canBack = false; - } - }, - end{ - { - canBack = false; - } - }; - public final String text = Bundles.getNotNull("tutorial."+name()+".text"); - - boolean androidOnly; - boolean desktopOnly; - - boolean canBack = true; - boolean canForward = true; - boolean canPlace = false; - boolean showBlock = false; - - int blockPlaceX = 0; - int blockPlaceY = 0; - int blockRotation = -1; - Block targetBlock = null; - - void update(Tutorial t){}; - void onSwitch(){} - } -} diff --git a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java index 23250f1a2b..cd917b1098 100644 --- a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java @@ -45,7 +45,7 @@ public class OverlayRenderer { int tiley = input.getBlockY(); //draw placement box - if ((input.recipe != null && state.inventory.hasItems(input.recipe.requirements) && (!ui.hasMouse() || mobile) + if ((input.recipe != null && (!ui.hasMouse() || mobile) && input.drawPlace())) { input.placeMode.draw(input, input.getBlockX(), @@ -55,7 +55,7 @@ public class OverlayRenderer { input.breakMode.draw(input, tilex, tiley, 0, 0); } else if (input.breakMode.delete && input.drawPlace() - && (input.recipe == null || !state.inventory.hasItems(input.recipe.requirements)) + && (input.recipe == null) && (input.placeMode.delete || input.breakMode.both || !mobile)) { if (input.breakMode == PlaceMode.holdDelete) diff --git a/core/src/io/anuke/mindustry/input/AndroidInput.java b/core/src/io/anuke/mindustry/input/AndroidInput.java index 5ca98187d6..36bb8f9a4f 100644 --- a/core/src/io/anuke/mindustry/input/AndroidInput.java +++ b/core/src/io/anuke/mindustry/input/AndroidInput.java @@ -7,7 +7,6 @@ import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.NetEvents; -import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Inputs; @@ -98,28 +97,12 @@ public class AndroidInput extends InputHandler{ mousex = Gdx.graphics.getWidth()/2; mousey = Gdx.graphics.getHeight()/2; } - - @Override - public boolean cursorNear(){ - return true; - } public Tile selected(){ Vector2 vec = Graphics.world(mousex, mousey); return world.tile(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize)); } - public void breakBlock(){ - Tile tile = selected(); - breaktime += Timers.delta(); - - if(breaktime >= tile.block().breaktime){ - brokeBlock = true; - breakBlock(tile.x, tile.y, true); - breaktime = 0f; - } - } - @Override public void update(){ enableHold = breakMode == PlaceMode.holdDelete; @@ -150,15 +133,6 @@ public class AndroidInput extends InputHandler{ if(sel == null) return; - if(warmup > warmupDelay && validBreak(sel.x, sel.y)){ - breaktime += Timers.delta(); - - if(breaktime > selected().block().breaktime){ - breakBlock(); - breaktime = 0; - } - } - mousex = lx; mousey = ly; }else{ @@ -169,23 +143,6 @@ public class AndroidInput extends InputHandler{ mousey = Mathf.clamp(mousey, 0, Gdx.graphics.getHeight()); } } - - @Override - public boolean tryPlaceBlock(int x, int y, boolean sound){ - if(recipe != null && - validPlace(x, y, recipe.result) && cursorNear() && - state.inventory.hasItems(recipe.requirements)){ - - placeBlock(x, y, recipe, rotation, true, sound); - - for(ItemStack stack : recipe.requirements){ - state.inventory.removeItem(stack); - } - - return true; - } - return false; - } public boolean breaking(){ return recipe == null; diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index db35a0e976..68b2694708 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -21,7 +21,6 @@ public class DesktopInput extends InputHandler{ float mousex, mousey; float endx, endy; private float controlx, controly; - private boolean enableHold = false; private boolean beganBreak; private boolean controlling; private final int index; @@ -178,17 +177,6 @@ public class DesktopInput extends InputHandler{ recipe = null; } - //block breaking - if(enableHold && Inputs.keyDown(section,"break") && cursor != null && validBreak(tilex(), tiley())){ - breaktime += Timers.delta(); - if(breaktime >= cursor.getBreakTime()){ - breakBlock(cursor.x, cursor.y, true); - breaktime = 0f; - } - }else{ - breaktime = 0f; - } - if(recipe != null){ showCursor = validPlace(tilex(), tiley(), recipe.result) && cursorNear(); } diff --git a/core/src/io/anuke/mindustry/input/GestureHandler.java b/core/src/io/anuke/mindustry/input/GestureHandler.java index c85ee2cadc..c87384196f 100644 --- a/core/src/io/anuke/mindustry/input/GestureHandler.java +++ b/core/src/io/anuke/mindustry/input/GestureHandler.java @@ -47,7 +47,7 @@ public class GestureHandler extends GestureAdapter{ if(input.isCursorVisible() && !Inputs.keyDown("select")) return false; if(!input.isCursorVisible() && !(input.recipe != null - && input.placeMode.lockCamera && state.inventory.hasItems(input.recipe.requirements)) && + && input.placeMode.lockCamera) && !(input.recipe == null && input.breakMode.lockCamera)){ float dx = deltaX*Core.camera.zoom/Core.cameraScale, dy = deltaY*Core.camera.zoom/Core.cameraScale; input.player.x -= dx; diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index 7397bcf9b9..868b2f95ca 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -4,16 +4,14 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.InputAdapter; import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.math.Vector2; -import io.anuke.mindustry.entities.BlockPlacer.PlaceRequest; +import io.anuke.mindustry.entities.BlockBuilder.BuildRequest; import io.anuke.mindustry.entities.ItemAnimationEffect; import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.net.Net; -import io.anuke.mindustry.net.NetEvents; import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.Recipe; import io.anuke.mindustry.ui.fragments.OverlayFragment; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.Placement; +import io.anuke.mindustry.world.Build; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Graphics; @@ -158,25 +156,20 @@ public abstract class InputHandler extends InputAdapter{ return true; } - public boolean tryPlaceBlock(int x, int y, boolean sound){ + public boolean tryPlaceBlock(int x, int y){ if(recipe != null && - validPlace(x, y, recipe.result) && !ui.hasMouse() && cursorNear() && - state.inventory.hasItems(recipe.requirements)){ + validPlace(x, y, recipe.result) && !ui.hasMouse() && cursorNear()){ - placeBlock(x, y, recipe, rotation, true, sound); - - for(ItemStack stack : recipe.requirements){ - state.inventory.removeItem(stack); - } + placeBlock(x, y, recipe, rotation); return true; } return false; } - public boolean tryDeleteBlock(int x, int y, boolean sound){ + public boolean tryDeleteBlock(int x, int y){ if(cursorNear() && validBreak(x, y)){ - breakBlock(x, y, sound); + breakBlock(x, y); return true; } return false; @@ -189,7 +182,7 @@ public abstract class InputHandler extends InputAdapter{ public boolean validPlace(int x, int y, Block type){ for(Tile tile : state.teams.get(player.team).cores){ if(tile.distanceTo(x * tilesize, y * tilesize) < coreBuildRange){ - return Placement.validPlace(player.team, x, y, type, rotation) && + return Build.validPlace(player.team, x, y, type, rotation) && Vector2.dst(player.x, player.y, x * tilesize, y * tilesize) < Player.placeDistance; } } @@ -198,35 +191,16 @@ public abstract class InputHandler extends InputAdapter{ } public boolean validBreak(int x, int y){ - return Placement.validBreak(player.team, x, y); + return Build.validBreak(player.team, x, y); } - public void placeBlock(int x, int y, Recipe recipe, int rotation, boolean effects, boolean sound){ + public void placeBlock(int x, int y, Recipe recipe, int rotation){ //todo multiplayer support - player.addPlaceBlock(new PlaceRequest(x, y, rotation, recipe)); - /* - if(!Net.client()){ //is server or singleplayer - threads.run(() -> Placement.placeBlock(player.team, x, y, recipe, rotation, effects, sound)); - } - - if(Net.active()){ - NetEvents.handlePlace(player, x, y, recipe, rotation); - } - - //todo fix this, call placed() - if(!Net.client()){ - //Tile tile = world.tile(x, y); - //if(tile != null) threads.run(() -> result.placed(tile)); - }*/ + player.addBuildRequest(new BuildRequest(x, y, rotation, recipe)); } - public void breakBlock(int x, int y, boolean sound){ - if(!Net.client()){ - threads.run(() -> Placement.breakBlock(player.team, x, y, true, sound)); - } - - if(Net.active()){ - NetEvents.handleBreak(x, y); - } + public void breakBlock(int x, int y){ + //todo multiplayer support + player.addBuildRequest(new BuildRequest(x, y)); } } diff --git a/core/src/io/anuke/mindustry/input/PlaceMode.java b/core/src/io/anuke/mindustry/input/PlaceMode.java index 1150f1cd2d..57f20ea5b5 100644 --- a/core/src/io/anuke/mindustry/input/PlaceMode.java +++ b/core/src/io/anuke/mindustry/input/PlaceMode.java @@ -8,7 +8,7 @@ import com.badlogic.gdx.math.Vector2; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.ui.fragments.ToolFragment; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.Placement; +import io.anuke.mindustry.world.Build; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Timers; @@ -55,7 +55,7 @@ public enum PlaceMode{ } public void tapped(InputHandler input, int tilex, int tiley){ - input.tryPlaceBlock(tilex, tiley, true); + input.tryPlaceBlock(tilex, tiley); } }, touch{ @@ -67,7 +67,7 @@ public enum PlaceMode{ } public void tapped(InputHandler input, int x, int y){ - input.tryPlaceBlock(x, y, true); + input.tryPlaceBlock(x, y); } }, none{ @@ -110,7 +110,7 @@ public enum PlaceMode{ } public void tapped(InputHandler input, int x, int y){ - input.tryDeleteBlock(x, y, true); + input.tryDeleteBlock(x, y); } }, areaDelete{ @@ -172,7 +172,7 @@ public enum PlaceMode{ tilex = this.rtilex; tiley = this.rtiley; endx = this.rendx; endy = this.rendy; - input.player.getPlaceQueue().clear(); + input.player.clearBuilding(); if(mobile){ ToolFragment t = input.frag.tool; @@ -186,13 +186,10 @@ public enum PlaceMode{ } } - boolean first = true; - for(int cx = tilex; cx <= endx; cx ++){ for(int cy = tiley; cy <= endy; cy ++){ - if(input.tryDeleteBlock(cx, cy, first)){ - first = false; - } + input.tryDeleteBlock(cx, cy); + } } } @@ -283,7 +280,7 @@ public enum PlaceMode{ int wx = tilex + px * Mathf.sign(endx - tilex), wy = tiley + py * Mathf.sign(endy - tiley); - if(!Placement.validPlace(input.player.team, wx, wy, block, rotation)){ + if(!Build.validPlace(input.player.team, wx, wy, block, rotation)){ Draw.color("placeInvalid"); }else{ Draw.color("accent"); @@ -315,22 +312,21 @@ public enum PlaceMode{ process(input, tilex, tiley, endx, endy); input.rotation = this.rotation; - input.player.getPlaceQueue().clear(); + input.player.clearBuilding(); boolean first = true; for(int x = 0; x <= Math.abs(this.rendx - this.rtilex); x += input.recipe.result.size){ for(int y = 0; y <= Math.abs(this.rendy - this.rtiley); y += input.recipe.result.size){ - if(input.tryPlaceBlock( + input.tryPlaceBlock( tilex + x * Mathf.sign(endx - tilex), - tiley + y * Mathf.sign(endy - tiley), first)){ - first = false; - } - + tiley + y * Mathf.sign(endy - tiley)); } } } void process(InputHandler input, int tilex, int tiley, int endx, int endy){ + + //todo hold shift to snap /* if(Math.abs(tilex - endx) > Math.abs(tiley - endy)){ endy = tiley; diff --git a/core/src/io/anuke/mindustry/net/NetEvents.java b/core/src/io/anuke/mindustry/net/NetEvents.java index db258b56f8..da224bf696 100644 --- a/core/src/io/anuke/mindustry/net/NetEvents.java +++ b/core/src/io/anuke/mindustry/net/NetEvents.java @@ -27,7 +27,7 @@ public class NetEvents { } @RemoteServer - public static void notifySomethingFromClient(Player player, int x, float y){ + public static void notifySomethingFromClient(Player player, int x, float y, String asdsad, long l){ } diff --git a/core/src/io/anuke/mindustry/net/Packets.java b/core/src/io/anuke/mindustry/net/Packets.java index 2e8fb58b0e..e2ec3aee77 100644 --- a/core/src/io/anuke/mindustry/net/Packets.java +++ b/core/src/io/anuke/mindustry/net/Packets.java @@ -11,7 +11,6 @@ import io.anuke.mindustry.gen.CallClient; import io.anuke.mindustry.io.Version; import io.anuke.mindustry.net.Packet.ImportantPacket; import io.anuke.mindustry.net.Packet.UnimportantPacket; -import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.world.Block; import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.EntityGroup; @@ -136,17 +135,13 @@ public class Packets { } public static class StateSyncPacket implements Packet, UnimportantPacket{ - public int[] items; + //todo fix item syncing public float countdown, time; public int enemies, wave; public long timestamp; @Override public void write(ByteBuffer buffer) { - for(int i = 0; i < items.length; i ++){ - buffer.putInt(items[i]); - } - buffer.putFloat(countdown); buffer.putFloat(time); buffer.putShort((short)enemies); @@ -156,12 +151,6 @@ public class Packets { @Override public void read(ByteBuffer buffer) { - items = new int[Item.getAllItems().size]; - - for(int i = 0; i < items.length; i ++){ - items[i] = buffer.getInt(); - } - countdown = buffer.getFloat(); time = buffer.getFloat(); enemies = buffer.getShort(); diff --git a/core/src/io/anuke/mindustry/resource/CarryItem.java b/core/src/io/anuke/mindustry/resource/CarryItem.java deleted file mode 100644 index b255904576..0000000000 --- a/core/src/io/anuke/mindustry/resource/CarryItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package io.anuke.mindustry.resource; - -public interface CarryItem { -} diff --git a/core/src/io/anuke/mindustry/resource/ItemStack.java b/core/src/io/anuke/mindustry/resource/ItemStack.java index 55f83f6ea5..c11bce57b1 100644 --- a/core/src/io/anuke/mindustry/resource/ItemStack.java +++ b/core/src/io/anuke/mindustry/resource/ItemStack.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.resource; -public class ItemStack implements CarryItem{ +public class ItemStack{ public Item item; public int amount; diff --git a/core/src/io/anuke/mindustry/resource/LiquidStack.java b/core/src/io/anuke/mindustry/resource/LiquidStack.java deleted file mode 100644 index 6d0714f6e9..0000000000 --- a/core/src/io/anuke/mindustry/resource/LiquidStack.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.anuke.mindustry.resource; - -public class LiquidStack implements CarryItem{ - public Liquid liquid; - public float amount; - - public LiquidStack(Liquid liquid, float amount){ - this.liquid = liquid; - this.amount = amount; - } - - public boolean equals(LiquidStack other){ - return other != null && other.liquid == liquid && other.amount == amount; - } -} diff --git a/core/src/io/anuke/mindustry/resource/Recipe.java b/core/src/io/anuke/mindustry/resource/Recipe.java index cb9e338f60..a21b3679e4 100644 --- a/core/src/io/anuke/mindustry/resource/Recipe.java +++ b/core/src/io/anuke/mindustry/resource/Recipe.java @@ -54,7 +54,7 @@ public class Recipe { return r; } - public static Array all(){ + public static Array getAllRecipes(){ return allRecipes; } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java index e3a582bb39..8b8db3f845 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/ColorPickDialog.java @@ -29,7 +29,7 @@ public class ColorPickDialog extends Dialog{ cons.accept(color); hide(); }).size(44, 48).pad(0).padBottom(-5.1f).get(); - button.setChecked(players[0].getColor().equals(color)); + button.setChecked(players[0].color.equals(color)); button.getStyle().imageUpColor = color; if(i%4 == 3){ diff --git a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java index 5c95d3b4c7..66ac0e17a4 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java @@ -42,7 +42,7 @@ public class HostDialog extends FloatingDialog{ Settings.save(); }); }).size(50f, 54f).get(); - button.update(() -> button.getStyle().imageUpColor = player.getColor()); + button.update(() -> button.getStyle().imageUpColor = player.color); }).width(w).height(70f).pad(4).colspan(3); content().row(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java index 32e8b179b2..3d6b4ae1d9 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java @@ -222,7 +222,7 @@ public class JoinDialog extends FloatingDialog { Settings.save(); }); }).size(50f, 54f).get(); - button.update(() -> button.getStyle().imageUpColor = player.getColor()); + button.update(() -> button.getStyle().imageUpColor = player.color); }).width(w).height(70f).pad(4); content().row(); content().add(pane).width(w + 34).pad(0); diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java index a2521ed7d8..64bfd9466c 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlocksFragment.java @@ -17,7 +17,6 @@ import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.BlockStats; import io.anuke.ucore.graphics.Draw; -import io.anuke.ucore.graphics.Hue; import io.anuke.ucore.scene.Element; import io.anuke.ucore.scene.Group; import io.anuke.ucore.scene.actions.Actions; @@ -40,6 +39,16 @@ public class BlocksFragment implements Fragment{ private boolean shown = true; private Recipe hoveredDescriptionRecipe; private IntSet itemset = new IntSet(); + private int[] tmpItems; + + { + int size = 0; + for(Item ignored : Item.getAllItems()){ + size ++; + } + + tmpItems = new int[size]; + } public void build(Group parent){ InputHandler input = control.input(0); @@ -55,7 +64,7 @@ public class BlocksFragment implements Fragment{ itemtable = new Table("button"); itemtable.setVisible(() -> input.recipe == null && !state.mode.infiniteResources); itemtable.update(() -> { - int[] items = state.inventory.readItems(); + int[] items = tmpItems; for(int i = 0; i < items.length; i ++){ if(itemset.contains(items[i]) != (items[i] > 0)){ updateItems(); @@ -186,10 +195,9 @@ public class BlocksFragment implements Fragment{ table.add(image).size(size + 8); image.update(() -> { - boolean has = (state.inventory.hasItems(r.requirements)); image.setTouchable(Touchable.enabled); for(Element e : istack.getChildren()){ - e.setColor(has ? Color.WHITE : Hue.lightness(0.33f)); + e.setColor(Color.WHITE); } for(Player player : players){ @@ -287,7 +295,7 @@ public class BlocksFragment implements Fragment{ Label reqlabel = new Label(""); reqlabel.update(()->{ - int current = state.inventory.getAmount(stack.item); + int current = stack.amount; String text = Mathf.clamp(current, 0, stack.amount) + "/" + stack.amount; reqlabel.setColor(current < stack.amount ? Colors.get("missingitems") : Color.WHITE); @@ -364,7 +372,7 @@ public class BlocksFragment implements Fragment{ }; int index = 0; - int[] items = state.inventory.readItems(); + int[] items = tmpItems; for(int i = 0; i < items.length; i ++){ int amount = items[i]; diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java index 3ffa9e2c3d..fbfe0e0051 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java @@ -118,7 +118,7 @@ public class PlayerListFragment implements Fragment{ }); button.add(stack).size(h); - button.labelWrap("[#" + player.getColor().toString().toUpperCase() + "]" + player.name).width(170f).pad(10); + button.labelWrap("[#" + player.color.toString().toUpperCase() + "]" + player.name).width(170f).pad(10); button.add().grow(); button.addImage("icon-admin").size(14*2).visible(() -> player.isAdmin && !(!player.isLocal && Net.server())).padRight(5); diff --git a/core/src/io/anuke/mindustry/ui/fragments/ToolFragment.java b/core/src/io/anuke/mindustry/ui/fragments/ToolFragment.java index 3b28de55c0..a4325d7fc7 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/ToolFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/ToolFragment.java @@ -3,7 +3,6 @@ package io.anuke.mindustry.ui.fragments; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Align; -import static io.anuke.mindustry.Vars.*; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.input.InputHandler; import io.anuke.mindustry.input.PlaceMode; @@ -12,6 +11,8 @@ import io.anuke.ucore.core.Graphics; import io.anuke.ucore.scene.Group; import io.anuke.ucore.scene.ui.layout.Table; +import static io.anuke.mindustry.Vars.*; + public class ToolFragment implements Fragment{ private Table tools; private InputHandler input; @@ -52,7 +53,7 @@ public class ToolFragment implements Fragment{ }); tools.setVisible(() -> - !state.is(State.menu) && mobile && ((input.recipe != null && state.inventory.hasItems(input.recipe.requirements) && + !state.is(State.menu) && mobile && ((input.recipe != null && input.placeMode == PlaceMode.cursor) || confirming) ); diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index b141aee4f2..d96810fba8 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -68,8 +68,6 @@ public class Block extends BaseBlock { public boolean liquid; /**whether this floor can be placed on.*/ public boolean placeableOn = true; - /**time it takes to break*/ - public float breaktime = 18; /**tile entity health*/ public int health = 40; /**base block explosiveness*/ diff --git a/core/src/io/anuke/mindustry/world/Placement.java b/core/src/io/anuke/mindustry/world/Build.java similarity index 80% rename from core/src/io/anuke/mindustry/world/Placement.java rename to core/src/io/anuke/mindustry/world/Build.java index d986d68bb4..ea7416a64e 100644 --- a/core/src/io/anuke/mindustry/world/Placement.java +++ b/core/src/io/anuke/mindustry/world/Build.java @@ -7,15 +7,15 @@ import io.anuke.mindustry.content.blocks.Blocks; import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.game.Team; -import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.Recipe; import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity; import io.anuke.ucore.core.Effects; import io.anuke.ucore.entities.Entities; -import static io.anuke.mindustry.Vars.*; +import static io.anuke.mindustry.Vars.tilesize; +import static io.anuke.mindustry.Vars.world; -public class Placement { +public class Build { private static final Rectangle rect = new Rectangle(); private static Array tempTiles = new Array<>(); @@ -28,17 +28,9 @@ public class Placement { Block block = tile.isLinked() ? tile.getLinked().block() : tile.block(); Recipe result = Recipe.getByResult(block); - if(result != null){ - for(ItemStack stack : result.requirements){ - state.inventory.addItem(stack.item, (int)(stack.amount * breakDropAmount)); - } - } + //todo add break results to core inventory - if(tile.block().drops != null){ - state.inventory.addItem(tile.block().drops.item, tile.block().drops.amount); - } - - if(sound) threads.run(() -> Effects.sound("break", x * tilesize, y * tilesize)); + if(sound) Effects.sound("break", x * tilesize, y * tilesize); if(!tile.block().isMultiblock() && !tile.isLinked()){ tile.setBlock(Blocks.air); @@ -56,7 +48,8 @@ public class Placement { return block; } - public static void placeBlock(Team team, int x, int y, Recipe recipe, int rotation, boolean effects, boolean sound){ + /**Places a BuildBlock at this location. Call validPlace first.*/ + public static void placeBlock(Team team, int x, int y, Recipe recipe, int rotation){ Tile tile = world.tile(x, y); Block result = recipe.result; @@ -86,23 +79,16 @@ public class Placement { toplace.setTeam(team); } } - - if(effects) Effects.effect(Fx.none, worldx * tilesize, worldy * tilesize); } } - }else if(effects){ - Effects.effect(Fx.none, x * tilesize, y * tilesize); - } - - if(effects && sound){ - threads.run(() -> Effects.sound("place", x * tilesize, y * tilesize)); } } + /**Returns whether a tile can be placed at this location by this team.*/ public static boolean validPlace(Team team, int x, int y, Block type, int rotation){ Recipe recipe = Recipe.getByResult(type); - if(recipe == null || !state.inventory.hasItems(recipe.requirements)){ + if(recipe == null){ return false; } @@ -121,7 +107,7 @@ public class Placement { if (e == null) return; //not sure why this happens? Rectangle rect = e.hitbox.getRect(e.x, e.y); - if (Placement.rect.overlaps(rect) && !e.isFlying()) { + if (Build.rect.overlaps(rect) && !e.isFlying()) { result[0] = true; } }); @@ -160,13 +146,12 @@ public class Placement { return false; } + /**Returns whether the tile at this position is breakable by this team*/ public static boolean validBreak(Team team, int x, int y) { Tile tile = world.tile(x, y); - if (tile == null || tile.block().unbreakable) return false; - - return (!tile.isLinked() || !tile.getLinked().block().unbreakable) && tile.breakable() - && (tile.getTeam() == Team.none || tile.getTeam() == team); + return tile != null && !tile.block().unbreakable + && (!tile.isLinked() || !tile.getLinked().block().unbreakable) && tile.breakable() && (tile.getTeam() == Team.none || tile.getTeam() == team); } } diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index 8bd8247cb4..b8a3944cdc 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -6,6 +6,7 @@ import com.badlogic.gdx.utils.reflect.ClassReflection; import io.anuke.mindustry.content.blocks.Blocks; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.game.Team; +import io.anuke.mindustry.resource.Recipe; import io.anuke.mindustry.world.blocks.types.Floor; import io.anuke.mindustry.world.blocks.types.modules.InventoryModule; import io.anuke.mindustry.world.blocks.types.modules.LiquidModule; @@ -132,10 +133,14 @@ public class Tile implements Position{ this.team = (byte)team.ordinal(); } - /**Returns the breaktime of the block, or the breaktime of the linked block, if this tile is linked.*/ + /**Returns the break time of the block, or the breaktime of the linked block, if this tile is linked.*/ public float getBreakTime(){ - Block block = block(); - return link == 0 ? block.breaktime : getLinked().block().breaktime; + Block block = target().block(); + if(Recipe.getByResult(block) != null){ + return Recipe.getByResult(block).cost; + }else{ + return 15f; + } } public void setBlock(Block type, int rotation){ diff --git a/core/src/io/anuke/mindustry/world/blocks/types/Rock.java b/core/src/io/anuke/mindustry/world/blocks/types/Rock.java index bc5e82dae6..86eadcd7f8 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/Rock.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/Rock.java @@ -8,7 +8,6 @@ public class Rock extends Block { super(name); shadow = name+"shadow"; breakable = true; - breaktime = 10; alwaysReplace = true; } }