This commit is contained in:
Anuken
2018-12-14 21:48:34 -05:00
38 changed files with 572 additions and 497 deletions

View File

@@ -45,10 +45,9 @@ public class Recipes implements ContentList{
new Recipe(effect, StorageBlocks.container, new ItemStack(Items.densealloy, 200));
new Recipe(effect, StorageBlocks.vault, new ItemStack(Items.densealloy, 500), new ItemStack(Items.thorium, 250));
//core disabled due to being broken
new Recipe(effect, StorageBlocks.core,
new ItemStack(Items.copper, 2000), new ItemStack(Items.densealloy, 1500),
new ItemStack(Items.silicon, 1500), new ItemStack(Items.thorium, 500),
new ItemStack(Items.copper, 2000), new ItemStack(Items.densealloy, 2000),
new ItemStack(Items.silicon, 1750), new ItemStack(Items.thorium, 1000),
new ItemStack(Items.surgealloy, 500), new ItemStack(Items.phasefabric, 750)
);

View File

@@ -16,7 +16,8 @@ import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Mathf;
public class Blocks extends BlockList implements ContentList{
public static Block air, blockpart, spawn, space, metalfloor, deepwater, water, lava, tar, stone, blackstone, dirt, sand, ice, snow, grass, shrub, rock, icerock, blackrock;
public static Block air, blockpart, spawn, space, metalfloor, deepwater, water, lava, tar, stone,
blackstone, dirt, sand, ice, snow, grass, shrub, rock, icerock, blackrock;
@Override
@@ -90,6 +91,7 @@ public class Blocks extends BlockList implements ContentList{
}};
lava = new Floor("lava"){{
drownTime = 100f;
liquidColor = Color.valueOf("ed5334");
speedMultiplier = 0.2f;
damageTaken = 0.5f;
@@ -103,6 +105,7 @@ public class Blocks extends BlockList implements ContentList{
}};
tar = new Floor("tar"){{
drownTime = 150f;
liquidColor = Color.valueOf("292929");
status = StatusEffects.tarred;
statusIntensity = 1f;

View File

@@ -1,10 +1,7 @@
package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx;
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;
@@ -43,17 +40,13 @@ import static io.anuke.mindustry.Vars.*;
* 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 = 100;
public final Saves saves;
public final Unlocks unlocks;
private Timer timerRPC= new Timer(), timerUnlock = new Timer();
private Timer timerRPC = new Timer(), timerUnlock = new Timer();
private boolean hiscore = false;
private boolean wasPaused = false;
private InputHandler[] inputs = {};
private ObjectMap<Sound, Long> soundMap = new ObjectMap<>();
private Throwable error;
public Control(){
@@ -78,17 +71,6 @@ public class Control extends Module{
unlocks.load();
Sounds.setFalloff(9000f);
Sounds.setPlayer((sound, volume) -> {
long time = TimeUtils.millis();
long value = soundMap.get(sound, 0L);
if(TimeUtils.timeSinceMillis(value) >= minSoundPeriod){
threads.runGraphics(() -> sound.play(volume));
soundMap.put(sound, time);
}
});
DefaultKeybinds.load();
Settings.defaultList(

View File

@@ -40,7 +40,6 @@ import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import static io.anuke.mindustry.Vars.*;
@@ -96,26 +95,24 @@ public class MapEditorDialog extends Dialog implements Disposable{
t.addImageTextButton("$text.editor.import", "icon-load-map", isize, () ->
createDialog("$text.editor.import",
"$text.editor.importmap", "$text.editor.importmap.description", "icon-load-map", (Runnable) loadDialog::show,
"$text.editor.importfile", "$text.editor.importfile.description", "icon-file", (Runnable) () -> {
Platform.instance.showFileChooser("$text.loadimage", "Map Files", file -> {
ui.loadGraphics(() -> {
try{
DataInputStream stream = new DataInputStream(file.read());
"$text.editor.importfile", "$text.editor.importfile.description", "icon-file", (Runnable) () ->
Platform.instance.showFileChooser("$text.loadimage", "Map Files", file -> ui.loadGraphics(() -> {
try{
DataInputStream stream = new DataInputStream(file.read());
MapMeta meta = MapIO.readMapMeta(stream);
MapTileData data = MapIO.readTileData(stream, meta, false);
MapMeta meta = MapIO.readMapMeta(stream);
MapTileData data = MapIO.readTileData(stream, meta, false);
editor.beginEdit(data, meta.tags, false);
view.clearStack();
}catch(Exception e){
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
Log.err(e);
}
});
}, true, mapExtension);
},
"$text.editor.importimage", "$text.editor.importimage.description", "icon-file-image", (Runnable)() -> {
Platform.instance.showFileChooser("$text.loadimage", "Image Files", file -> {
editor.beginEdit(data, meta.tags, false);
view.clearStack();
}catch(Exception e){
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
Log.err(e);
}
}), true, mapExtension),
"$text.editor.importimage", "$text.editor.importimage.description", "icon-file-image", (Runnable)() ->
Platform.instance.showFileChooser("$text.loadimage", "Image Files", file ->
ui.loadGraphics(() -> {
try{
MapTileData data = MapIO.readLegacyPixmap(new Pixmap(file));
@@ -126,12 +123,11 @@ public class MapEditorDialog extends Dialog implements Disposable{
ui.showError(Bundles.format("text.editor.errorimageload", Strings.parseException(e, false)));
Log.err(e);
}
});
}, true, "png");
}));
}), true, "png")
));
t.addImageTextButton("$text.editor.export", "icon-save-map", isize, () -> createDialog("$text.editor.export",
"$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Runnable) () -> {
"$text.editor.exportfile", "$text.editor.exportfile.description", "icon-file", (Runnable) () ->
Platform.instance.showFileChooser("$text.saveimage", "Map Files", file -> {
file = file.parent().child(file.nameWithoutExtension() + "." + mapExtension);
FileHandle result = file;
@@ -147,8 +143,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
Log.err(e);
}
});
}, false, mapExtension);
}));
}, false, mapExtension)));
t.row();
@@ -171,8 +166,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
}
});
loadDialog = new MapLoadDialog(map -> {
loadDialog = new MapLoadDialog(map ->
ui.loadGraphics(() -> {
try(DataInputStream stream = new DataInputStream(map.stream.get())){
MapMeta meta = MapIO.readMapMeta(stream);
@@ -180,12 +174,11 @@ public class MapEditorDialog extends Dialog implements Disposable{
editor.beginEdit(data, meta.tags, false);
view.clearStack();
}catch(IOException e){
}catch(Exception e){
ui.showError(Bundles.format("text.editor.errormapload", Strings.parseException(e, false)));
Log.err(e);
}
});
});
}));
setFillParent(true);
@@ -261,7 +254,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
* 2) icon name
* 3) listener
*/
private FloatingDialog createDialog(String title, Object... arguments){
private void createDialog(String title, Object... arguments){
FloatingDialog dialog = new FloatingDialog(title);
float h = 90f;
@@ -278,18 +271,15 @@ public class MapEditorDialog extends Dialog implements Disposable{
listenable.run();
dialog.hide();
menu.hide();
}).left().get();
}).left().margin(0).get();
button.clearChildren();
button.table("button", t -> {
t.addImage(iconname).size(16 * 3);
t.update(() -> t.background(button.getClickListener().isOver() ? "button-over" : "button"));
}).padLeft(-10).padBottom(-3).size(h);
button.addImage(iconname).size(16 * 3).padLeft(10);
button.table(t -> {
t.add(name).growX().wrap();
t.row();
t.add(description).color(Color.GRAY).growX().wrap();
}).growX().padLeft(8);
}).growX().pad(10f).padLeft(5);
button.row();
@@ -298,8 +288,6 @@ public class MapEditorDialog extends Dialog implements Disposable{
dialog.addCloseButton();
dialog.show();
return dialog;
}
@Override
@@ -562,9 +550,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
ImageButton button = new ImageButton("white", "clear-toggle");
button.clicked(() -> editor.setDrawBlock(block));
button.resizeImage(8 * 4f);
button.getImageCell().setActor(stack);
button.addChild(stack);
button.getImage().remove();
button.replaceImage(stack);
button.update(() -> button.setChecked(editor.getDrawBlock() == block));
group.add(button);
content.add(button).size(50f);

View File

@@ -283,9 +283,9 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
@Override
public void drawShadow(float offsetX, float offsetY){
float x = snappedX(), y = snappedY();
float scl = mech.flying ? 1f : boostHeat/2f;
float scl = mech.flying ? 1f : boostHeat / 2f;
Draw.rect(mech.iconRegion, x + offsetX*scl, y + offsetY*scl, rotation - 90);
Draw.rect(mech.iconRegion, x + offsetX * scl, y + offsetY * scl, rotation - 90);
}
@Override
@@ -356,9 +356,9 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
float angT = i == 0 ? 0 : Mathf.randomSeedRange(i + 1, 60f);
float lenT = i == 0 ? 0 : Mathf.randomSeedRange(i + 2, 1f) - 1f;
Draw.rect(stack.item.region,
x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT),
y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT),
itemSize, itemSize, rotation);
x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT),
y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT),
itemSize, itemSize, rotation);
}
}
@@ -369,7 +369,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
public void drawStats(){
float x = snappedX(), y = snappedY();
Draw.color(Color.BLACK, team.color, healthf() + Mathf.absin(Timers.time(), healthf()*5f, 1f - healthf()));
Draw.color(Color.BLACK, team.color, healthf() + Mathf.absin(Timers.time(), healthf() * 5f, 1f - healthf()));
Draw.alpha(hitTime / hitDuration);
Draw.rect(getPowerCellRegion(), x + Angles.trnsx(rotation, mech.cellTrnsY, 0f), y + Angles.trnsy(rotation, mech.cellTrnsY, 0f), rotation - 90);
Draw.color();
@@ -426,7 +426,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
Core.font.setUseIntegerPositions(ints);
}
/**Draw all current build requests. Does not draw the beam effect, only the positions.*/
/** Draw all current build requests. Does not draw the beam effect, only the positions. */
public void drawBuildRequests(){
for(BuildRequest request : getPlaceQueue()){
if(getCurrentRequest() == request) continue;
@@ -442,16 +442,16 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
float rad = Mathf.absin(Timers.time(), 7f, 1f) + block.size * tilesize / 2f - 1;
Lines.square(
request.x * tilesize + block.offset(),
request.y * tilesize + block.offset() - 1,
rad);
request.x * tilesize + block.offset(),
request.y * tilesize + block.offset() - 1,
rad);
Draw.color(Palette.remove);
Lines.square(
request.x * tilesize + block.offset(),
request.y * tilesize + block.offset(),
rad);
request.x * tilesize + block.offset(),
request.y * tilesize + block.offset(),
rad);
}else{
//draw place request
Lines.stroke(2f);
@@ -461,16 +461,16 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
float rad = Mathf.absin(Timers.time(), 7f, 1f) - 2f + request.recipe.result.size * tilesize / 2f;
Lines.square(
request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset() - 1,
rad);
request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset() - 1,
rad);
Draw.color(Palette.accent);
Lines.square(
request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset(),
rad);
request.x * tilesize + request.recipe.result.offset(),
request.y * tilesize + request.recipe.result.offset(),
rad);
}
}
@@ -605,9 +605,10 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
float xa = Inputs.getAxis(section, "move_x");
float ya = Inputs.getAxis(section, "move_y");
movement.y += ya * speed;
movement.x += xa * speed;
if(!Inputs.keyDown("gridMode")){
movement.y += ya * speed;
movement.x += xa * speed;
}
Vector2 vec = Graphics.world(control.input(playerIndex).getMouseX(), control.input(playerIndex).getMouseY());
pointerX = vec.x;
@@ -699,8 +700,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
getHitbox(rect);
rect.x -= expansion;
rect.y -= expansion;
rect.width += expansion*2f;
rect.height += expansion*2f;
rect.width += expansion * 2f;
rect.height += expansion * 2f;
isBoosting = EntityQuery.collisions().overlapsTile(rect) || distanceTo(targetX, targetY) > 85f;
@@ -737,7 +738,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
if(target != null && distanceTo(target) > getWeapon().getAmmo().getRange()){
target = null;
}else if(target != null){
target = ((Tile)target).entity;
target = ((Tile) target).entity;
}
}
@@ -746,14 +747,14 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
}
}
}else if(target.isValid() || (target instanceof TileEntity && ((TileEntity) target).damaged() && target.getTeam() == team &&
mech.canHeal && distanceTo(target) < getWeapon().getAmmo().getRange())){
mech.canHeal && distanceTo(target) < getWeapon().getAmmo().getRange())){
//rotate toward and shoot the target
if(mech.turnCursor){
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f);
}
Vector2 intercept =
Predict.intercept(x, y, target.getX(), target.getY(), target.getVelocity().x - velocity.x, target.getVelocity().y - velocity.y, getWeapon().getAmmo().bullet.speed);
Predict.intercept(x, y, target.getX(), target.getY(), target.getVelocity().x - velocity.x, target.getVelocity().y - velocity.y, getWeapon().getAmmo().bullet.speed);
pointerX = intercept.x;
pointerY = intercept.y;
@@ -764,7 +765,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
}else if(isShooting()){
Vector2 vec = Graphics.world(control.input(playerIndex).getMouseX(),
control.input(playerIndex).getMouseY());
control.input(playerIndex).getMouseY());
pointerX = vec.x;
pointerY = vec.y;
@@ -777,7 +778,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
//region utility methods
/** Resets all values of the player.*/
/** Resets all values of the player. */
public void reset(){
resetNoAdd();
@@ -791,6 +792,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
placeQueue.clear();
dead = true;
trail.clear();
target = null;
moveTarget = null;
carrier = null;
health = maxHealth();
boostHeat = drownTime = hitTime = 0f;

View File

@@ -173,15 +173,19 @@ public interface BuilderTrait extends Entity{
default void updateBuilding(Unit unit){
//remove already completed build requests
removal.clear();
for(BuildRequest request : getPlaceQueue()){
if((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) ||
(!request.breaking && world.tile(request.x, request.y).block() == request.recipe.result)){
removal.add(request);
}
for(BuildRequest req : getPlaceQueue()){
removal.add(req);
}
for(BuildRequest req : removal){
getPlaceQueue().removeValue(req, true);
getPlaceQueue().clear();
for(BuildRequest request : removal){
if(!((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) ||
(!request.breaking &&
(world.tile(request.x, request.y).getRotation() == request.rotation || !request.recipe.result.rotate)
&& world.tile(request.x, request.y).block() == request.recipe.result))){
getPlaceQueue().addLast(request);
}
}
BuildRequest current = getCurrentRequest();

View File

@@ -76,7 +76,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
Effects.effect(ExplosionFx.explosion, unit);
Effects.shake(2f, 2f, unit);
//must run afterwards so the unit's group is not null
//must run afterwards so the unit's group is not null when sending the removal packet
threads.runDelay(unit::remove);
}

View File

@@ -22,8 +22,7 @@ import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import static io.anuke.mindustry.Vars.headless;
import static io.anuke.mindustry.Vars.players;
import static io.anuke.mindustry.Vars.*;
public class AlphaDrone extends FlyingUnit {
static final float followDistance = 80f;
@@ -62,7 +61,7 @@ public class AlphaDrone extends FlyingUnit {
}
}
if(!leader.isShooting && distanceTo(leader) < 8f){
if(!leader.isShooting && distanceTo(leader) < 7f){
Call.onAlphaDroneFade(AlphaDrone.this);
}
}
@@ -71,8 +70,9 @@ public class AlphaDrone extends FlyingUnit {
@Remote(called = Loc.server)
public static void onAlphaDroneFade(BaseUnit drone){
if(drone == null) return;
drone.remove();
Effects.effect(UnitFx.pickup, drone);
//must run afterwards so the unit's group is not null when sending the removal packet
threads.runDelay(drone::remove);
}
@Override

View File

@@ -17,6 +17,8 @@ import io.anuke.ucore.util.Strings;
import io.anuke.ucore.util.ThreadArray;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import static io.anuke.mindustry.Vars.*;
@@ -185,8 +187,12 @@ public class Saves{
return Strings.formatMillis(current == this ? totalPlaytime : meta.timePlayed);
}
public long getTimestamp(){
return meta.timestamp;
}
public String getDate(){
return meta.date;
return SimpleDateFormat.getDateTimeInstance().format(new Date(meta.timestamp));
}
public Map getMap(){

View File

@@ -65,6 +65,7 @@ public class Unlocks{
save();
}
@SuppressWarnings("unchecked")
public void load(){
unlocked = Settings.getObject("unlockset", ObjectMap.class, ObjectMap::new);
}

View File

@@ -25,6 +25,8 @@ public class DefaultKeybinds{
"rotate", new Axis(Input.SCROLL),
"dash", Input.SHIFT_LEFT,
"drop_unit", Input.SHIFT_LEFT,
"gridMode", Input.CONTROL_LEFT,
"gridModeShift", Input.SHIFT_LEFT,
new Category("view"),
"zoom_hold", Input.CONTROL_LEFT,
"zoom", new Axis(Input.SCROLL),

View File

@@ -217,10 +217,10 @@ public class DesktopInput extends InputHandler{
}else if(selected != null){
//only begin shooting if there's no cursor event
if (!tileTapped(selected) && !tryTapPlayer(Graphics.mouseWorld().x, Graphics.mouseWorld().y) && player.getPlaceQueue().size == 0 && !droppingItem &&
!tryBeginMine(selected) && player.getMineTile() == null) {
!tryBeginMine(selected) && player.getMineTile() == null && !ui.chatfrag.chatOpen()) {
player.isShooting = true;
}
}else{ //if it's out of bounds, shooting is just fine
}else if(!ui.chatfrag.chatOpen()){ //if it's out of bounds, shooting is just fine
player.isShooting = true;
}
}else if(Inputs.keyTap(section, "deselect") && (recipe != null || mode != none || player.isBuilding()) &&

View File

@@ -4,15 +4,12 @@ import io.anuke.mindustry.game.Difficulty;
import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.maps.Map;
import java.text.SimpleDateFormat;
import java.util.Date;
import static io.anuke.mindustry.Vars.world;
public class SaveMeta{
public int version;
public int build;
public String date;
public long timestamp;
public long timePlayed;
public int sector;
public GameMode mode;
@@ -20,10 +17,10 @@ public class SaveMeta{
public int wave;
public Difficulty difficulty;
public SaveMeta(int version, long date, long timePlayed, int build, int sector, int mode, String map, int wave, Difficulty difficulty){
public SaveMeta(int version, long timestamp, long timePlayed, int build, int sector, int mode, String map, int wave, Difficulty difficulty){
this.version = version;
this.build = build;
this.date = SimpleDateFormat.getDateTimeInstance().format(new Date(date));
this.timestamp = timestamp;
this.timePlayed = timePlayed;
this.sector = sector;
this.mode = GameMode.values()[mode];

View File

@@ -86,6 +86,10 @@ public class Sectors{
return grid.get(Bits.getLeftShort(position), Bits.getRightShort(position));
}
public Iterable<Sector> getSectors(){
return grid.values();
}
public Difficulty getDifficulty(Sector sector){
if(sector.difficulty == 0){
return Difficulty.hard;
@@ -150,6 +154,7 @@ public class Sectors{
save();
}
@SuppressWarnings("unchecked")
public void load(){
for(Sector sector : grid.values()){
sector.texture.dispose();

View File

@@ -261,6 +261,7 @@ public class Administration{
Settings.save();
}
@SuppressWarnings("unchecked")
private void load(){
playerInfo = Settings.getObject("player-info", ObjectMap.class, ObjectMap::new);
bannedIPs = Settings.getObject("banned-ips", Array.class, Array::new);

View File

@@ -25,11 +25,11 @@ import java.io.IOException;
import static io.anuke.mindustry.Vars.*;
@SuppressWarnings("unchecked")
public class Net{
private static boolean server;
private static boolean active;
private static boolean clientLoaded;
private static String lastIP;
private static Array<Object> packetQueue = new Array<>();
private static ObjectMap<Class<?>, Consumer> clientListeners = new ObjectMap<>();
private static ObjectMap<Class<?>, BiConsumer<Integer, Object>> serverListeners = new ObjectMap<>();
@@ -106,7 +106,6 @@ public class Net{
*/
public static void connect(String ip, int port, Runnable success){
try{
lastIP = ip + ":" + port;
if(!active){
clientProvider.connect(ip, port, success);
active = true;
@@ -119,11 +118,6 @@ public class Net{
}
}
/**Returns the last IP connected to.*/
public static String getLastIP() {
return lastIP;
}
/**
* Host a server at an address.
*/

View File

@@ -11,7 +11,7 @@ public class ItemImage extends Stack{
public ItemImage(TextureRegion region, Supplier<CharSequence> text){
Table t = new Table().left().bottom();
t.label(text);
t.label(text).name("item-label");
add(new Image(region));
add(t);
@@ -22,7 +22,7 @@ public class ItemImage extends Stack{
if(stack.amount != 0){
Table t = new Table().left().bottom();
t.add(stack.amount + "");
t.add(stack.amount + "").name("item-label");
add(t);
}
}

View File

@@ -12,21 +12,15 @@ public class MenuButton extends TextButton{
public MenuButton(String icon, String text, String description, Runnable clicked){
super("default");
float s = 66f;
clicked(clicked);
clearChildren();
margin(0);
table(t -> {
t.addImage(icon).size(14 * 3);
t.update(() -> t.setBackground(getClickListener().isVisualPressed() ? "button-down" : getClickListener().isOver() ? "button-over" : "button"));
}).size(s - 5, s);
t.addImage(icon).size(14 * 3).padLeft(6);
table(t -> {
t.add(text).wrap().growX().get().setAlignment(Align.center, Align.left);
if(description != null){
t.row();

View File

@@ -1,23 +1,22 @@
package io.anuke.mindustry.ui;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.Element;
import io.anuke.ucore.scene.event.InputEvent;
import io.anuke.ucore.scene.event.InputListener;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.ui.layout.Container;
import static io.anuke.mindustry.Vars.renderer;
public class Minimap extends Table{
public class Minimap extends Container<Element>{
public Minimap(){
super("pane");
super(new Element(){
TextureRegion r = new TextureRegion();
margin(5);
Element elem = new Element(){
@Override
public void draw(){
if(renderer.minimap.getRegion() == null) return;
@@ -28,7 +27,12 @@ public class Minimap extends Table{
renderer.minimap.drawEntities(x, y, width, height);
}
}
};
});
background("pane");
size(140f);
margin(5f);
addListener(new InputListener(){
public boolean scrolled(InputEvent event, float x, float y, int amount){
@@ -37,7 +41,7 @@ public class Minimap extends Table{
}
});
elem.update(() -> {
update(() -> {
Element e = Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true);
if(e != null && e.isDescendantOf(this)){
@@ -46,7 +50,5 @@ public class Minimap extends Table{
Core.scene.setScrollFocus(null);
}
});
add(elem).size(140f, 140f);
}
}

View File

@@ -279,9 +279,7 @@ public class JoinDialog extends FloatingDialog{
button.left();
button.row();
button.add("[lightgray]" + (host.players != 1 ? Bundles.format("text.players", host.players) :
Bundles.format("text.players.single", host.players)));
button.row();
button.add("[lightgray]" + host.address).pad(4).left();
Bundles.format("text.players.single", host.players))).padBottom(5);
}
void connect(String ip, int port){
@@ -310,6 +308,7 @@ public class JoinDialog extends FloatingDialog{
return UIUtils.portrait() ? 350f : 500f;
}
@SuppressWarnings("unchecked")
private void loadServers(){
servers = Settings.getObject("server-list", Array.class, Array::new);
}

View File

@@ -159,6 +159,26 @@ public class SectorsDialog extends FloatingDialog{
});
clicked(() -> clicked = true);
this.focus();
}
private void focus(){
Sector focusSector = null;
long newestTimestamp = 0;
for(Sector sector : world.sectors.getSectors()){
if(sector.hasSave()){
long timestamp = sector.getSave().getTimestamp();
if(timestamp > newestTimestamp){
focusSector = sector;
newestTimestamp = timestamp;
}
}
}
if(focusSector != null) {
panX = (focusSector.x + 0.5f) * sectorSize;
panY = (focusSector.y + 0.5f) * sectorSize;
}
}
@Override

View File

@@ -109,7 +109,7 @@ public class HudFragment extends Fragment{
}
cont.update(() -> {
if(Inputs.keyTap("toggle_menus") && !ui.chatfrag.chatOpen()){
if(!Inputs.keyDown("gridMode") && Inputs.keyTap("toggle_menus") && !ui.chatfrag.chatOpen()){
toggleMenus();
}
});
@@ -139,7 +139,7 @@ public class HudFragment extends Fragment{
if(Net.hasClient()){
t.label(() -> ping.get(Net.getPing())).visible(Net::client).colspan(2);
}
}).size(-1).visible(() -> Settings.getBool("fps")).update(t -> t.setTranslation(0, (!waves.isVisible() ? wavetable.getHeight() : Math.min(wavetable.getTranslation().y, wavetable.getHeight())) )).get();
}).size(-1).visible(() -> Settings.getBool("fps")).update(t -> t.setTranslation(0, (!waves.isVisible() ? wavetable.getHeight() : Math.min(wavetable.getTranslation().y, wavetable.getHeight())))).get();
//make wave box appear below rest of menu
if(mobile){
@@ -149,7 +149,7 @@ public class HudFragment extends Fragment{
//minimap
parent.fill(t -> t.top().right().add(new Minimap())
.visible(() -> !state.is(State.menu) && Settings.getBool("minimap")));
.visible(() -> !state.is(State.menu) && Settings.getBool("minimap")));
//paused table
parent.fill(t -> {
@@ -198,7 +198,7 @@ public class HudFragment extends Fragment{
return coreAttackOpacity > 0;
});
t.table("button", top -> top.add("$text.coreattack").pad(2)
.update(label -> label.setColor(Hue.mix(Color.ORANGE, Color.SCARLET, Mathf.absin(Timers.time(), 2f, 1f)))));
.update(label -> label.setColor(Hue.mix(Color.ORANGE, Color.SCARLET, Mathf.absin(Timers.time(), 2f, 1f)))));
});
//'saving' indicator
@@ -218,7 +218,7 @@ public class HudFragment extends Fragment{
}
});
table.margin(12);
table.addImage("icon-check").size(16*2).pad(3);
table.addImage("icon-check").size(16 * 2).pad(3);
table.add(text).wrap().width(280f).get().setAlignment(Align.center, Align.center);
table.pack();
@@ -231,7 +231,7 @@ public class HudFragment extends Fragment{
Actions.run(() -> container.actions(Actions.translateBy(0, table.getPrefHeight(), 1f, Interpolation.fade), Actions.removeActor())));
}
/**Show unlock notification for a new recipe.*/
/** Show unlock notification for a new recipe. */
public void showUnlock(Recipe recipe){
//if there's currently no unlock notification...
@@ -268,11 +268,11 @@ public class HudFragment extends Fragment{
container.top().add(table);
container.setTranslation(0, table.getPrefHeight());
container.actions(Actions.translateBy(0, -table.getPrefHeight(), 1f, Interpolation.fade), Actions.delay(4f),
//nesting actions() calls is necessary so the right prefHeight() is used
Actions.run(() -> container.actions(Actions.translateBy(0, table.getPrefHeight(), 1f, Interpolation.fade), Actions.run(() -> {
lastUnlockTable = null;
lastUnlockLayout = null;
}), Actions.removeActor())));
//nesting actions() calls is necessary so the right prefHeight() is used
Actions.run(() -> container.actions(Actions.translateBy(0, table.getPrefHeight(), 1f, Interpolation.fade), Actions.run(() -> {
lastUnlockTable = null;
lastUnlockLayout = null;
}), Actions.removeActor())));
lastUnlockTable = container;
lastUnlockLayout = in;

View File

@@ -3,6 +3,7 @@ package io.anuke.mindustry.ui.fragments;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.game.EventType.WorldLoadGraphicsEvent;
@@ -17,6 +18,8 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.OreBlock;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.input.Input;
import io.anuke.ucore.scene.Group;
import io.anuke.ucore.scene.actions.Actions;
import io.anuke.ucore.scene.event.Touchable;
@@ -38,6 +41,19 @@ public class PlacementFragment extends Fragment{
boolean shown = true;
boolean lastGround;
//TODO make this configurable
final Input[] inputGrid = {
Input.NUM_1, Input.NUM_2, Input.NUM_3, Input.NUM_4,
Input.Q, Input.W, Input.E, Input.R,
Input.A, Input.S, Input.D, Input.F,
Input.Z, Input.X, Input.C, Input.V
}, inputCatGrid = {
Input.NUM_1, Input.NUM_2,
Input.Q, Input.W,
Input.A, Input.S,
Input.Z, Input.X, Input.C, Input.V
};
public PlacementFragment(){
Events.on(WorldLoadGraphicsEvent.class, event -> {
currentCategory = Category.turret;
@@ -47,6 +63,42 @@ public class PlacementFragment extends Fragment{
});
}
boolean gridUpdate(InputHandler input){
if(!Inputs.keyDown("gridMode") || ui.chatfrag.chatOpen()) return false;
if(Inputs.keyDown("gridModeShift")){ //select category
int i = 0;
for(Input key : inputCatGrid){
if(Inputs.keyDown(key)){
input.recipe = Recipe.getByCategory(Category.values()[i]).first();
currentCategory = input.recipe.category;
}
i++;
}
return true;
}else if(Inputs.keyDown("select")){ //mouse eyedropper select
Tile tile = world.tileWorld(Graphics.mouseWorld().x, Graphics.mouseWorld().y);
if(tile != null){
tile = tile.target();
Recipe tryRecipe = Recipe.getByResult(tile.block());
if(tryRecipe != null && control.unlocks.isUnlocked(tryRecipe)){
input.recipe = tryRecipe;
currentCategory = input.recipe.category;
return true;
}
}
}else{ //select block
int i = 0;
Array<Recipe> recipes = Recipe.getByCategory(currentCategory);
for(Input key : inputGrid){
if(Inputs.keyDown(key))
input.recipe = (i < recipes.size && control.unlocks.isUnlocked(recipes.get(i))) ? recipes.get(i) : null;
i++;
}
}
return false;
}
@Override
public void build(Group parent){
parent.fill(full -> {
@@ -74,7 +126,7 @@ public class PlacementFragment extends Fragment{
boolean[] unlocked = {false};
ImageButton button = blockTable.addImageButton("icon-locked", "select", 8*4, () -> {
ImageButton button = blockTable.addImageButton("icon-locked", "select", 8 * 4, () -> {
if(control.unlocks.isUnlocked(recipe)){
input.recipe = input.recipe == recipe ? null : recipe;
}
@@ -111,8 +163,8 @@ public class PlacementFragment extends Fragment{
frame.table("button-edge-2", top -> {
topTable = top;
top.add(new Table()).growX().update(topTable -> {
if((tileDisplayBlock() == null && lastDisplay == getSelected() && !lastGround) ||
(tileDisplayBlock() != null && lastDisplay == tileDisplayBlock() && lastGround)) return;
if((tileDisplayBlock() == null && lastDisplay == getSelected() && !lastGround) || (tileDisplayBlock() != null && lastDisplay == tileDisplayBlock() && lastGround))
return;
topTable.clear();
topTable.top().left().margin(5);
@@ -123,14 +175,14 @@ public class PlacementFragment extends Fragment{
if(lastDisplay != null){ //show selected recipe
topTable.table(header -> {
header.left();
header.add(new ImageStack(lastDisplay.getCompactIcon())).size(8*4);
header.add(new ImageStack(lastDisplay.getCompactIcon())).size(8 * 4);
header.labelWrap(() ->
!control.unlocks.isUnlocked(Recipe.getByResult(lastDisplay)) ? Bundles.get("text.blocks.unknown") : lastDisplay.formalName)
.left().width(190f).padLeft(5);
!control.unlocks.isUnlocked(Recipe.getByResult(lastDisplay)) ? Bundles.get("text.blocks.unknown") : lastDisplay.formalName)
.left().width(190f).padLeft(5);
header.add().growX();
if(control.unlocks.isUnlocked(Recipe.getByResult(lastDisplay))){
header.addButton("?", "clear-partial", () -> ui.content.show(Recipe.getByResult(lastDisplay)))
.size(8 * 5).padTop(-5).padRight(-5).right().grow();
.size(8 * 5).padTop(-5).padRight(-5).right().grow();
}
}).growX().left();
topTable.row();
@@ -141,7 +193,7 @@ public class PlacementFragment extends Fragment{
for(ItemStack stack : Recipe.getByResult(lastDisplay).requirements){
req.table(line -> {
line.left();
line.addImage(stack.item.region).size(8*2);
line.addImage(stack.item.region).size(8 * 2);
line.add(stack.item.localizedName()).color(Color.LIGHT_GRAY).padLeft(2).left();
line.labelWrap(() -> {
TileEntity core = players[0].getClosestCore();
@@ -159,13 +211,13 @@ public class PlacementFragment extends Fragment{
}else if(tileDisplayBlock() != null){ //show selected tile
lastDisplay = tileDisplayBlock();
topTable.add(new ImageStack(lastDisplay.getDisplayIcon(hoverTile))).size(8*4);
topTable.add(new ImageStack(lastDisplay.getDisplayIcon(hoverTile))).size(8 * 4);
topTable.labelWrap(lastDisplay.getDisplayName(hoverTile)).left().width(190f).padLeft(5);
}
});
}).colspan(3).fillX().visible(() -> getSelected() != null || tileDisplayBlock() != null).touchable(Touchable.enabled);
frame.row();
frame.addImage("blank").color(Palette.accent).colspan(3).height(3*2).growX();
frame.addImage("blank").color(Palette.accent).colspan(3).height(3 * 2).growX();
frame.row();
frame.table("pane-2", blocksSelect -> {
blocksSelect.margin(4).marginTop(0);
@@ -181,21 +233,24 @@ public class PlacementFragment extends Fragment{
for(Category cat : Category.values()){
if(Recipe.getByCategory(cat).isEmpty()) continue;
categories.addImageButton("icon-" + cat.name(), "clear-toggle", 16*2, () -> {
categories.addImageButton("icon-" + cat.name(), "clear-toggle", 16 * 2, () -> {
currentCategory = cat;
rebuildCategory.run();
}).group(group).update(i -> i.setChecked(currentCategory == cat));
if(cat.ordinal() %2 == 1) categories.row();
if(cat.ordinal() % 2 == 1) categories.row();
}
}).touchable(Touchable.enabled);
rebuildCategory.run();
frame.update(() -> {
if(gridUpdate(input)) rebuildCategory.run();
});
});
});
}
/**Returns the currently displayed block in the top box.*/
/** Returns the currently displayed block in the top box. */
Block getSelected(){
Block toDisplay = null;
@@ -226,12 +281,12 @@ public class PlacementFragment extends Fragment{
return toDisplay;
}
/**Returns the block currently being hovered over in the world.*/
/** Returns the block currently being hovered over in the world. */
Block tileDisplayBlock(){
return hoverTile == null ? null : hoverTile.block().synthetic() ? hoverTile.block() : hoverTile.floor() instanceof OreBlock ? hoverTile.floor() : null;
}
/**Show or hide the placement menu.*/
/** Show or hide the placement menu. */
void toggle(float t, Interpolation ip){
toggler.clearActions();
if(shown){

View File

@@ -101,6 +101,7 @@ public class Tile implements PosTrait, TargetTrait{
return -1;
}
@SuppressWarnings("unchecked")
public <T extends TileEntity> T entity(){
return (T) entity;
}

View File

@@ -35,7 +35,6 @@ public class Conveyor extends Block{
private TextureRegion[][] regions = new TextureRegion[7][4];
protected float speed = 0f;
protected float carryCapacity = 8f;
protected Conveyor(String name){
super(name);
@@ -342,9 +341,9 @@ public class Conveyor extends Block{
public Array<Object> getDebugInfo(Tile tile){
ConveyorEntity entity = tile.entity();
Array<Object> arr = super.getDebugInfo(tile);
arr.addAll(Array.with(
"clogHeat", entity.clogHeat,
"sleeping", entity.isSleeping()
arr.addAll(Array.<Object>with(
"clogHeat", entity.clogHeat,
"sleeping", entity.isSleeping()
));
return arr;
}

View File

@@ -87,6 +87,7 @@ public class Consumers{
return map.containsKey(type);
}
@SuppressWarnings("unchecked")
public <T extends Consume> T get(Class<T> type){
if(!map.containsKey(type)){
throw new IllegalArgumentException("Block does not contain consumer of type '" + type + "'!");