Fixed overflow gate, splitter

This commit is contained in:
Anuken
2018-07-13 10:11:42 -04:00
parent 2fcb3c4420
commit 93bec04c92
8 changed files with 127 additions and 91 deletions

View File

@@ -37,9 +37,7 @@ import static io.anuke.mindustry.Vars.*;
* This class is not created in the headless server. * This class is not created in the headless server.
*/ */
public class Control extends Module{ public class Control extends Module{
/** /** Minimum period of time between the same sound being played.*/
* Minimum period of time between the same sound being played.
*/
private static final long minSoundPeriod = 100; private static final long minSoundPeriod = 100;
private boolean hiscore = false; private boolean hiscore = false;

View File

@@ -34,6 +34,7 @@ import java.util.Locale;
import static io.anuke.mindustry.Vars.control; import static io.anuke.mindustry.Vars.control;
import static io.anuke.mindustry.Vars.players; import static io.anuke.mindustry.Vars.players;
import static io.anuke.mindustry.Vars.threads;
import static io.anuke.ucore.scene.actions.Actions.*; import static io.anuke.ucore.scene.actions.Actions.*;
public class UI extends SceneModule{ public class UI extends SceneModule{
@@ -231,6 +232,16 @@ public class UI extends SceneModule{
}); });
} }
public void loadLogic(Callable call){
loadfrag.show();
Timers.runTask(7f, () -> {
threads.run(() -> {
call.run();
threads.runGraphics(loadfrag::hide);
});
});
}
public void showTextInput(String title, String text, String def, TextFieldFilter filter, Consumer<String> confirmed){ public void showTextInput(String title, String text, String def, TextFieldFilter filter, Consumer<String> confirmed){
new Dialog(title, "dialog"){{ new Dialog(title, "dialog"){{
content().margin(30).add(text).padRight(6f); content().margin(30).add(text).padRight(6f);

View File

@@ -33,20 +33,17 @@ import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.scene.Group; import io.anuke.ucore.scene.Group;
import io.anuke.ucore.scene.builders.imagebutton; import io.anuke.ucore.scene.builders.imagebutton;
import io.anuke.ucore.scene.builders.table; import io.anuke.ucore.scene.builders.table;
import io.anuke.ucore.scene.event.Touchable;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.input.PlaceMode.*; import static io.anuke.mindustry.input.PlaceMode.*;
public class MobileInput extends InputHandler implements GestureListener{ public class MobileInput extends InputHandler implements GestureListener{
/** /** Maximum speed the player can pan. */
* Maximum speed the player can pan.
*/
private static final float maxPanSpeed = 1.3f; private static final float maxPanSpeed = 1.3f;
private static Rectangle r1 = new Rectangle(), r2 = new Rectangle(); private static Rectangle r1 = new Rectangle(), r2 = new Rectangle();
/** /** Distance to edge of screen to start panning. */
* Distance to edge of screen to start panning.
*/
private final float edgePan = io.anuke.ucore.scene.ui.layout.Unit.dp.scl(60f); private final float edgePan = io.anuke.ucore.scene.ui.layout.Unit.dp.scl(60f);
//gesture data //gesture data
@@ -54,53 +51,31 @@ public class MobileInput extends InputHandler implements GestureListener{
private Vector2 vector = new Vector2(); private Vector2 vector = new Vector2();
private float initzoom = -1; private float initzoom = -1;
private boolean zoomed = false; private boolean zoomed = false;
/** /** Set of completed guides. */
* Set of completed guides.
*/
private ObjectSet<String> guides = new ObjectSet<>(); private ObjectSet<String> guides = new ObjectSet<>();
/** /** Position where the player started dragging a line. */
* Position where the player started dragging a line.
*/
private int lineStartX, lineStartY; private int lineStartX, lineStartY;
/** /** Animation scale for line. */
* Animation scale for line.
*/
private float lineScale; private float lineScale;
/** /** Animation data for crosshair. */
* Animation data for crosshair.
*/
private float crosshairScale; private float crosshairScale;
private TargetTrait lastTarget; private TargetTrait lastTarget;
/** /** List of currently selected tiles to place. */
* List of currently selected tiles to place.
*/
private Array<PlaceRequest> selection = new Array<>(); private Array<PlaceRequest> selection = new Array<>();
/** /** Place requests to be removed. */
* Place requests to be removed.
*/
private Array<PlaceRequest> removals = new Array<>(); private Array<PlaceRequest> removals = new Array<>();
/** /** Whether or not the player is currently shifting all placed tiles. */
* Whether or not the player is currently shifting all placed tiles.
*/
private boolean selecting; private boolean selecting;
/** /** Whether the player is currently in line-place mode. */
* Whether the player is currently in line-place mode.
*/
private boolean lineMode; private boolean lineMode;
/** /** Current place mode. */
* Current place mode.
*/
private PlaceMode mode = none; private PlaceMode mode = none;
/** /** Whether no recipe was available when switching to break mode. */
* Whether no recipe was available when switching to break mode.
*/
private Recipe lastRecipe; private Recipe lastRecipe;
/** /** Last placed request. Used for drawing block overlay. */
* Last placed request. Used for drawing block overlay.
*/
private PlaceRequest lastPlaced; private PlaceRequest lastPlaced;
public MobileInput(Player player){ public MobileInput(Player player){
@@ -110,9 +85,7 @@ public class MobileInput extends InputHandler implements GestureListener{
//region utility methods //region utility methods
/** /** Check and assign targets for a specific position. */
* Check and assign targets for a specific position.
*/
void checkTargets(float x, float y){ void checkTargets(float x, float y){
synchronized(Entities.entityLock){ synchronized(Entities.entityLock){
Unit unit = Units.getClosestEnemy(player.getTeam(), x, y, 20f, u -> true); Unit unit = Units.getClosestEnemy(player.getTeam(), x, y, 20f, u -> true);
@@ -130,16 +103,12 @@ public class MobileInput extends InputHandler implements GestureListener{
} }
} }
/** /** Returns whether this tile is in the list of requests, or at least colliding with one. */
* Returns whether this tile is in the list of requests, or at least colliding with one.
*/
boolean hasRequest(Tile tile){ boolean hasRequest(Tile tile){
return getRequest(tile) != null; return getRequest(tile) != null;
} }
/** /** Returns whether this block overlaps any selection requests. */
* Returns whether this block overlaps any selection requests.
*/
boolean checkOverlapPlacement(int x, int y, Block block){ boolean checkOverlapPlacement(int x, int y, Block block){
r2.setSize(block.size * tilesize); r2.setSize(block.size * tilesize);
r2.setCenter(x * tilesize + block.offset(), y * tilesize + block.offset()); r2.setCenter(x * tilesize + block.offset(), y * tilesize + block.offset());
@@ -159,9 +128,7 @@ public class MobileInput extends InputHandler implements GestureListener{
return false; return false;
} }
/** /** Returns the selection request that overlaps this tile, or null. */
* Returns the selection request that overlaps this tile, or null.
*/
PlaceRequest getRequest(Tile tile){ PlaceRequest getRequest(Tile tile){
r2.setSize(tilesize); r2.setSize(tilesize);
r2.setCenter(tile.worldx(), tile.worldy()); r2.setCenter(tile.worldx(), tile.worldy());
@@ -250,6 +217,8 @@ public class MobileInput extends InputHandler implements GestureListener{
margin(5); margin(5);
defaults().size(60f); defaults().size(60f);
touchable(Touchable.enabled);
//Add a cancel button //Add a cancel button
new imagebutton("icon-cancel", 16 * 2f, () -> { new imagebutton("icon-cancel", 16 * 2f, () -> {
mode = none; mode = none;
@@ -297,6 +266,8 @@ public class MobileInput extends InputHandler implements GestureListener{
margin(5); margin(5);
defaults().size(60f); defaults().size(60f);
touchable(Touchable.enabled);
//Add a break button. //Add a break button.
new imagebutton("icon-break", "toggle", 16 * 2f, () -> { new imagebutton("icon-break", "toggle", 16 * 2f, () -> {
mode = mode == breaking ? recipe == null ? none : placing : breaking; mode = mode == breaking ? recipe == null ? none : placing : breaking;
@@ -311,6 +282,8 @@ public class MobileInput extends InputHandler implements GestureListener{
margin(5); margin(5);
defaults().size(60f); defaults().size(60f);
touchable(Touchable.enabled);
//Add a 'cancel building' button. //Add a 'cancel building' button.
new imagebutton("icon-cancel", 16 * 2f, player::clearBuilding); new imagebutton("icon-cancel", 16 * 2f, player::clearBuilding);

View File

@@ -134,6 +134,8 @@ public class SaveIO{
FileHandle backup = file.sibling(file.name() + "-backup." + file.extension()); FileHandle backup = file.sibling(file.name() + "-backup." + file.extension());
if(backup.exists()){ if(backup.exists()){
load(new InflaterInputStream(backup.read())); load(new InflaterInputStream(backup.read()));
}else{
throw new RuntimeException(e);
} }
} }
} }

View File

@@ -166,21 +166,18 @@ public class LoadDialog extends FloatingDialog{
} }
public void runLoadSave(SaveSlot slot){ public void runLoadSave(SaveSlot slot){
ui.loadfrag.show(); hide();
ui.paused.hide();
Timers.runTask(3f, () -> { ui.loadLogic(() -> {
ui.loadfrag.hide();
hide();
try{ try{
slot.load(); slot.load();
state.set(State.playing); state.set(State.playing);
ui.paused.hide();
}catch(Exception e){ }catch(Exception e){
Log.err(e); Log.err(e);
ui.paused.hide();
state.set(State.menu); state.set(State.menu);
logic.reset(); logic.reset();
ui.showError("$text.save.corrupted"); threads.runGraphics(() -> ui.showError("$text.save.corrupted"));
} }
}); });
} }

View File

@@ -52,6 +52,7 @@ public class Edges{
} }
public static Tile getFacingEdge(Tile tile, Tile other){ public static Tile getFacingEdge(Tile tile, Tile other){
if(!tile.block().isMultiblock()) return tile;
int size = tile.block().size; int size = tile.block().size;
return world.tile(tile.x + Mathf.clamp(other.x - tile.x, -(size - 1) / 2, (size / 2)), return world.tile(tile.x + Mathf.clamp(other.x - tile.x, -(size - 1) / 2, (size / 2)),
tile.y + Mathf.clamp(other.y - tile.y, -(size - 1) / 2, (size / 2))); tile.y + Mathf.clamp(other.y - tile.y, -(size - 1) / 2, (size / 2)));

View File

@@ -1,7 +1,9 @@
package io.anuke.mindustry.world.blocks.distribution; package io.anuke.mindustry.world.blocks.distribution;
import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Edges;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
public class OverflowGate extends Splitter{ public class OverflowGate extends Splitter{
@@ -9,22 +11,35 @@ public class OverflowGate extends Splitter{
public OverflowGate(String name){ public OverflowGate(String name){
super(name); super(name);
hasItems = true; hasItems = true;
speed = 1f;
} }
@Override @Override
Tile getTileTarget(Item item, Tile dest, Tile source, boolean flip){ public void update(Tile tile){
int dir = source.relativeTo(dest.x, dest.y); SplitterEntity entity = tile.entity();
if(dir == -1) return null; if(entity.lastItem != null){
Tile to = dest.getNearby(dir); entity.time += 1f/speed * Timers.delta();
Tile target = getTileTarget(tile, entity.lastItem, entity.lastInput, false);
if((!to.block().acceptItem(item, to, dest) || if(target != null && (entity.time >= 1f)){
(to.block().instantTransfer && source.block().instantTransfer))){ getTileTarget(tile, entity.lastItem, entity.lastInput, true);
Tile a = dest.getNearby(Mathf.mod(dir - 1, 4)); target.block().handleItem(entity.lastItem, target, Edges.getFacingEdge(tile, target));
Tile b = dest.getNearby(Mathf.mod(dir + 1, 4)); entity.items.remove(entity.lastItem, 1);
boolean ac = !(a.block().instantTransfer && source.block().instantTransfer) && entity.lastItem = null;
a.block().acceptItem(item, a, dest); }
boolean bc = !(b.block().instantTransfer && source.block().instantTransfer) && }
b.block().acceptItem(item, b, dest); }
Tile getTileTarget(Tile tile, Item item, int from, boolean flip){
if(from == -1) return null;
Tile to = tile.getNearby((from + 2) % 4);
Tile edge = Edges.getFacingEdge(tile, to);
if(!to.block().acceptItem(item, to, edge) || (to.block() instanceof OverflowGate)){
Tile a = tile.getNearby(Mathf.mod(from - 1, 4));
Tile b = tile.getNearby(Mathf.mod(from + 1, 4));
boolean ac = a.block().acceptItem(item, a, edge) && !(a.block() instanceof OverflowGate);
boolean bc = b.block().acceptItem(item, b, edge) && !(b.block() instanceof OverflowGate);
if(!ac && !bc){ if(!ac && !bc){
return null; return null;
@@ -35,14 +50,12 @@ public class OverflowGate extends Splitter{
}else if(bc && !ac){ }else if(bc && !ac){
to = b; to = b;
}else{ }else{
if(dest.getDump() == 0){ if(tile.getDump() == 0){
to = a; to = a;
if(flip) if(flip) tile.setDump((byte) 1);
dest.setDump((byte) 1);
}else{ }else{
to = b; to = b;
if(flip) if(flip) tile.setDump((byte) 0);
dest.setDump((byte) 0);
} }
} }
} }

View File

@@ -1,22 +1,24 @@
package io.anuke.mindustry.world.blocks.distribution; package io.anuke.mindustry.world.blocks.distribution;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.BarType; import io.anuke.mindustry.world.BarType;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Edges; import io.anuke.mindustry.world.Edges;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockGroup; import io.anuke.mindustry.world.meta.BlockGroup;
import io.anuke.ucore.core.Timers;
public class Splitter extends Block{ public class Splitter extends Block{
protected float speed = 30f; protected float speed = 9f;
public Splitter(String name){ public Splitter(String name){
super(name); super(name);
solid = true; solid = true;
instantTransfer = true;
update = true; update = true;
hasItems = false; hasItems = true;
itemCapacity = 1;
group = BlockGroup.transportation; group = BlockGroup.transportation;
} }
@@ -28,29 +30,68 @@ public class Splitter extends Block{
} }
@Override @Override
public boolean acceptItem(Item item, Tile tile, Tile source){ public void update(Tile tile){
Tile to = getTileTarget(item, tile, source, false); SplitterEntity entity = tile.entity();
if(entity.lastItem != null){
entity.time += 1f/speed * Timers.delta();
Tile target = getTileTarget(tile, entity.lastItem, entity.lastInput);
return to != null; if(target != null && (entity.time >= 1f)){
target.block().handleItem(entity.lastItem, target, Edges.getFacingEdge(tile, target));
entity.items.remove(entity.lastItem, 1);
entity.lastItem = null;
}
}
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source){
SplitterEntity entity = tile.entity();
return entity.lastItem == null;
} }
@Override @Override
public void handleItem(Item item, Tile tile, Tile source){ public void handleItem(Item item, Tile tile, Tile source){
Tile to = getTileTarget(item, tile, source, true); SplitterEntity entity = tile.entity();
to.block().handleItem(item, to, Edges.getFacingEdge(tile, to)); entity.items.add(item, 1);
entity.lastItem = item;
entity.time = 0f;
entity.lastInput = tile.relativeTo(source.x, source.y);
} }
Tile getTileTarget(Item item, Tile tile, Tile source, boolean flip){ Tile getTileTarget(Tile tile, Item item, int from){
Array<Tile> proximity = tile.entity.proximity(); Array<Tile> proximity = tile.entity.proximity();
int counter = tile.getDump(); int counter = tile.getDump();
for(int i = 0; i < proximity.size; i++){ for(int i = 0; i < proximity.size; i++){
Tile other = proximity.get((i + counter) % proximity.size); Tile other = proximity.get((i + counter) % proximity.size);
if(flip) tile.setDump((byte) ((tile.getDump() + 1) % proximity.size)); if(tile.relativeTo(other.x, other.y) == from) continue;
if(other != source && !(source.block().instantTransfer && other.block().instantTransfer) && !(other.block() instanceof Splitter) && tile.setDump((byte) ((tile.getDump() + 1) % proximity.size));
other.block().acceptItem(item, other, Edges.getFacingEdge(tile, other))){ if(other.block().acceptItem(item, other, Edges.getFacingEdge(tile, other))){
return other; return other;
} }
} }
return null; return null;
} }
@Override
public int removeStack(Tile tile, Item item, int amount){
SplitterEntity entity = tile.entity();
int result = super.removeStack(tile, item, amount);
if(result != 0 && item == entity.lastItem){
entity.lastItem = null;
}
return result;
}
@Override
public TileEntity getEntity(){
return new SplitterEntity();
}
public class SplitterEntity extends TileEntity{
Item lastItem;
int lastInput;
float time;
}
} }