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