Merge branch '6.0' of https://github.com/Anuken/Mindustry into object-config

# Conflicts:
#	core/src/mindustry/entities/traits/BuilderTrait.java
#	core/src/mindustry/entities/type/TileEntity.java
#	core/src/mindustry/game/EventType.java
#	core/src/mindustry/game/Schematics.java
#	core/src/mindustry/input/InputHandler.java
#	core/src/mindustry/io/TypeIO.java
#	core/src/mindustry/world/Block.java
#	core/src/mindustry/world/blocks/distribution/Sorter.java
This commit is contained in:
Anuken
2020-03-03 21:33:03 -05:00
1356 changed files with 28653 additions and 24877 deletions

View File

@@ -5,6 +5,7 @@ import arc.Graphics.*;
import arc.Graphics.Cursor.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.scene.*;
import arc.scene.event.*;
import arc.scene.ui.*;
@@ -13,7 +14,8 @@ import arc.util.ArcAnnotate.*;
import arc.util.*;
import mindustry.*;
import mindustry.core.GameState.*;
import mindustry.entities.traits.BuilderTrait.*;
import mindustry.entities.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
@@ -26,6 +28,7 @@ import static mindustry.Vars.*;
import static mindustry.input.PlaceMode.*;
public class DesktopInput extends InputHandler{
private Vec2 movement = new Vec2();
/** Current cursor type. */
private Cursor cursorType = SystemCursor.arrow;
/** Position where the player started dragging a line. */
@@ -44,12 +47,12 @@ public class DesktopInput extends InputHandler{
@Override
public void buildUI(Group group){
group.fill(t -> {
t.bottom().update(() -> t.getColor().a = Mathf.lerpDelta(t.getColor().a, player.isBuilding() ? 1f : 0f, 0.15f));
t.bottom().update(() -> t.getColor().a = Mathf.lerpDelta(t.getColor().a, player.builder().isBuilding() ? 1f : 0f, 0.15f));
t.visible(() -> Core.settings.getBool("hints") && selectRequests.isEmpty());
t.touchable(() -> t.getColor().a < 0.1f ? Touchable.disabled : Touchable.childrenOnly);
t.table(Styles.black6, b -> {
b.defaults().left();
b.label(() -> Core.bundle.format(!player.isBuilding ? "resumebuilding" : "pausebuilding", Core.keybinds.get(Binding.pause_building).key.toString())).style(Styles.outlineLabel);
b.label(() -> Core.bundle.format(!isBuilding ? "resumebuilding" : "pausebuilding", Core.keybinds.get(Binding.pause_building).key.toString())).style(Styles.outlineLabel);
b.row();
b.label(() -> Core.bundle.format("cancelbuilding", Core.keybinds.get(Binding.clear_building).key.toString())).style(Styles.outlineLabel);
b.row();
@@ -67,7 +70,7 @@ public class DesktopInput extends InputHandler{
Core.keybinds.get(Binding.schematic_flip_y).key.toString())).style(Styles.outlineLabel);
b.row();
b.table(a -> {
a.addImageTextButton("$schematic.add", Icon.saveSmall, this::showSchematicSave).colspan(2).size(250f, 50f).disabled(f -> lastSchematic == null || lastSchematic.file != null);
a.addImageTextButton("$schematic.add", Icon.save, this::showSchematicSave).colspan(2).size(250f, 50f).disabled(f -> lastSchematic == null || lastSchematic.file != null);
});
}).margin(6f);
});
@@ -132,11 +135,13 @@ public class DesktopInput extends InputHandler{
@Override
public void update(){
super.update();
if(net.active() && Core.input.keyTap(Binding.player_list)){
ui.listfrag.toggle();
}
if(((player.getClosestCore() == null && player.isDead()) || state.isPaused()) && !ui.chatfrag.shown()){
if((player.dead() || state.isPaused()) && !ui.chatfrag.shown()){
//move camera around
float camSpeed = !Core.input.keyDown(Binding.dash) ? 3f : 8f;
Core.camera.position.add(Tmp.v1.setZero().add(Core.input.axis(Binding.move_x), Core.input.axis(Binding.move_y)).nor().scl(Time.delta() * camSpeed));
@@ -145,10 +150,27 @@ public class DesktopInput extends InputHandler{
Core.camera.position.x += Mathf.clamp((Core.input.mouseX() - Core.graphics.getWidth() / 2f) * 0.005f, -1, 1) * camSpeed;
Core.camera.position.y += Mathf.clamp((Core.input.mouseY() - Core.graphics.getHeight() / 2f) * 0.005f, -1, 1) * camSpeed;
}
}else if(!player.dead()){
Core.camera.position.lerpDelta(player, 0.08f);
}
//TODO remove: debug unit possession
if(Core.input.keyTap(Binding.select)){
Unitc unit = Units.closest(state.rules.defaultTeam, Core.input.mouseWorld().x, Core.input.mouseWorld().y, 40f, u -> true);
if(unit != null){
unit.hitbox(Tmp.r1);
if(Tmp.r1.contains(Core.input.mouseWorld())){
player.unit(unit);
}
}
}
if(!player.dead() && !state.isPaused() && !(Core.scene.getKeyboardFocus() instanceof TextField)){
updateMovement(player.unit());
}
if(Core.input.keyRelease(Binding.select)){
player.isShooting = false;
isShooting = false;
}
if(!state.is(State.menu) && Core.input.keyTap(Binding.minimap) && !scene.hasDialog() && !(scene.getKeyboardFocus() instanceof TextField)){
@@ -158,11 +180,12 @@ public class DesktopInput extends InputHandler{
if(state.is(State.menu) || Core.scene.hasDialog()) return;
//zoom camera
if((!Core.scene.hasScroll() || Core.input.keyDown(Binding.diagonal_placement)) && !ui.chatfrag.shown() && Math.abs(Core.input.axisTap(Binding.zoom)) > 0 && !Core.input.keyDown(Binding.rotateplaced) && (Core.input.keyDown(Binding.diagonal_placement) || ((!isPlacing() || !block.rotate) && selectRequests.isEmpty()))){
if((!Core.scene.hasScroll() || Core.input.keyDown(Binding.diagonal_placement)) && !ui.chatfrag.shown() && Math.abs(Core.input.axisTap(Binding.zoom)) > 0
&& !Core.input.keyDown(Binding.rotateplaced) && (Core.input.keyDown(Binding.diagonal_placement) || ((!isPlacing() || !block.rotate) && selectRequests.isEmpty()))){
renderer.scaleCamera(Core.input.axisTap(Binding.zoom));
}
if(player.isDead()){
if(player.dead()){
cursorType = SystemCursor.arrow;
return;
}
@@ -174,8 +197,8 @@ public class DesktopInput extends InputHandler{
mode = none;
}
if(player.isShooting && !canShoot()){
player.isShooting = false;
if(isShooting && !canShoot()){
isShooting = false;
}
if(isPlacing()){
@@ -222,7 +245,7 @@ public class DesktopInput extends InputHandler{
cursorType = ui.unloadCursor;
}
if(!isPlacing() && Math.abs(Core.input.axisTap(Binding.rotate)) > 0 && Core.input.keyDown(Binding.rotateplaced) && cursor.block().rotate){
if(cursor.interactable(player.team()) && !isPlacing() && Math.abs(Core.input.axisTap(Binding.rotate)) > 0 && Core.input.keyDown(Binding.rotateplaced) && cursor.block().rotate){
Call.rotateBlock(player, cursor, Core.input.axisTap(Binding.rotate) > 0);
}
}
@@ -256,7 +279,7 @@ public class DesktopInput extends InputHandler{
table.row();
table.left().margin(0f).defaults().size(48f).left();
table.addImageButton(Icon.pasteSmall, Styles.clearPartiali, () -> {
table.addImageButton(Icon.paste, Styles.clearPartiali, () -> {
ui.schematics.show();
});
}
@@ -270,9 +293,9 @@ public class DesktopInput extends InputHandler{
int rawCursorX = world.toTile(Core.input.mouseWorld().x), rawCursorY = world.toTile(Core.input.mouseWorld().y);
// automatically pause building if the current build queue is empty
if(Core.settings.getBool("buildautopause") && player.isBuilding && !player.isBuilding()){
player.isBuilding = false;
player.buildWasAutoPaused = true;
if(Core.settings.getBool("buildautopause") && isBuilding && !player.builder().isBuilding()){
isBuilding = false;
buildWasAutoPaused = true;
}
if(!selectRequests.isEmpty()){
@@ -288,11 +311,11 @@ public class DesktopInput extends InputHandler{
}
if(Core.input.keyTap(Binding.deselect)){
player.setMineTile(null);
player.miner().mineTile(null);
}
if(Core.input.keyTap(Binding.clear_building)){
player.clearBuilding();
player.builder().clearBuilding();
}
if(Core.input.keyTap(Binding.schematic_select) && !Core.scene.hasKeyboard()){
@@ -344,8 +367,8 @@ public class DesktopInput extends InputHandler{
}
if(Core.input.keyTap(Binding.pause_building)){
player.isBuilding = !player.isBuilding;
player.buildWasAutoPaused = false;
isBuilding = !isBuilding;
buildWasAutoPaused = false;
}
if((cursorX != lastLineX || cursorY != lastLineY) && isPlacing() && mode == placing){
@@ -374,12 +397,12 @@ public class DesktopInput extends InputHandler{
deleting = true;
}else if(selected != null){
//only begin shooting if there's no cursor event
if(!tileTapped(selected) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && (player.buildQueue().size == 0 || !player.isBuilding) && !droppingItem &&
!tryBeginMine(selected) && player.getMineTile() == null && !Core.scene.hasKeyboard()){
player.isShooting = true;
if(!tileTapped(selected) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && (player.builder().requests().size == 0 || !player.builder().isBuilding()) && !droppingItem &&
!tryBeginMine(selected) && player.miner().mineTile() == null && !Core.scene.hasKeyboard()){
isShooting = true;
}
}else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine
player.isShooting = true;
isShooting = true;
}
}else if(Core.input.keyTap(Binding.deselect) && isPlacing()){
block = null;
@@ -398,7 +421,7 @@ public class DesktopInput extends InputHandler{
if(Core.input.keyDown(Binding.select) && mode == none && !isPlacing() && deleting){
BuildRequest req = getRequest(cursorX, cursorY);
if(req != null && req.breaking){
player.buildQueue().remove(req);
player.builder().requests().remove(req);
}
}else{
deleting = false;
@@ -429,7 +452,7 @@ public class DesktopInput extends InputHandler{
if(sreq != null){
if(getRequest(sreq.x, sreq.y, sreq.block.size, sreq) != null){
player.buildQueue().remove(sreq, true);
player.builder().requests().remove(sreq, true);
}
sreq = null;
}
@@ -472,4 +495,94 @@ public class DesktopInput extends InputHandler{
selectRequests.clear();
}
}
protected void updateMovement(Unitc unit){
boolean omni = !(unit instanceof WaterMovec);
float speed = unit.type().speed;
float xa = Core.input.axis(Binding.move_x);
float ya = Core.input.axis(Binding.move_y);
movement.set(xa, ya).nor().scl(speed);
float mouseAngle = Angles.mouseAngle(unit.x(), unit.y());
boolean aimCursor = omni && isShooting && unit.type().hasWeapons();
if(aimCursor){
unit.lookAt(mouseAngle);
}else{
if(!unit.vel().isZero(0.01f)) unit.lookAt(unit.vel().angle());
}
if(omni){
unit.moveAt(movement, unit.type().accel);
}else{
unit.moveAt(Tmp.v2.trns(unit.rotation(), movement.len()), unit.type().accel);
if(!movement.isZero()){
unit.vel().rotateTo(movement.angle(), unit.type().rotateSpeed * Time.delta());
}
}
unit.aim(Core.input.mouseWorld());
unit.controlWeapons(true, isShooting);
/*
Tile tile = unit.tileOn();
boolean canMove = !Core.scene.hasKeyboard() || ui.minimapfrag.shown();
//TODO implement
boolean isBoosting = Core.input.keyDown(Binding.dash) && !mech.flying;
//if player is in solid block
if(tile != null && tile.solid()){
isBoosting = true;
}
float speed = isBoosting && unit.type().flying ? mech.boostSpeed : mech.speed;
if(mech.flying){
//prevent strafing backwards, have a penalty for doing so
float penalty = 0.2f; //when going 180 degrees backwards, reduce speed to 0.2x
speed *= Mathf.lerp(1f, penalty, Angles.angleDist(rotation, velocity.angle()) / 180f);
}
movement.setZero();
float xa = Core.input.axis(Binding.move_x);
float ya = Core.input.axis(Binding.move_y);
if(!(Core.scene.getKeyboardFocus() instanceof TextField)){
movement.y += ya * speed;
movement.x += xa * speed;
}
if(Core.input.keyDown(Binding.mouse_move)){
movement.x += Mathf.clamp((Core.input.mouseX() - Core.graphics.getWidth() / 2f) * 0.005f, -1, 1) * speed;
movement.y += Mathf.clamp((Core.input.mouseY() - Core.graphics.getHeight() / 2f) * 0.005f, -1, 1) * speed;
}
Vec2 vec = Core.input.mouseWorld(control.input.getMouseX(), control.input.getMouseY());
pointerX = vec.x;
pointerY = vec.y;
updateShooting();
movement.limit(speed).scl(Time.delta());
if(canMove){
velocity.add(movement.x, movement.y);
}else{
isShooting = false;
}
float prex = x, prey = y;
updateVelocityStatus();
moved = dst(prex, prey) > 0.001f;
if(canMove){
float baseLerp = mech.getRotationAlpha(this);
if(!isShooting() || !mech.faceTarget){
if(!movement.isZero()){
rotation = Mathf.slerpDelta(rotation, mech.flying ? velocity.angle() : movement.angle(), 0.13f * baseLerp);
}
}else{
float angle = control.input.mouseAngle(x, y);
this.rotation = Mathf.slerpDelta(this.rotation, angle, 0.1f * baseLerp);
}
}*/
}
}

View File

@@ -17,17 +17,15 @@ import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.entities.effect.*;
import mindustry.entities.traits.BuilderTrait.*;
import mindustry.entities.type.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.game.Teams.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.input.Placement.*;
import mindustry.net.*;
import mindustry.net.Administration.*;
import mindustry.net.*;
import mindustry.type.*;
import mindustry.ui.fragments.*;
import mindustry.world.*;
@@ -56,6 +54,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public int rotation;
public boolean droppingItem;
public Group uiGroup;
public boolean isShooting, isBuilding = true, buildWasAutoPaused = false;
protected @Nullable Schematic lastSchematic;
protected GestureDetector detector;
@@ -67,23 +66,51 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
//methods to override
@Remote(called = Loc.server, unreliable = true)
public static void transferItemEffect(Item item, float x, float y, Itemsc to){
if(to == null) return;
createItemTransfer(item, x, y, to, null);
}
@Remote(called = Loc.server, unreliable = true)
public static void transferItemToUnit(Item item, float x, float y, Itemsc to){
if(to == null) return;
createItemTransfer(item, x, y, to, () -> to.addItem(item));
}
@Remote(called = Loc.server, unreliable = true)
public static void transferItemTo(Item item, int amount, float x, float y, Tile tile){
if(tile == null || tile.entity == null || tile.entity.items() == null) return;
for(int i = 0; i < Mathf.clamp(amount / 3, 1, 8); i++){
Time.run(i * 3, () -> createItemTransfer(item, x, y, tile, () -> {}));
}
tile.entity.items().add(item, amount);
}
public static void createItemTransfer(Item item, float x, float y, Position to, Runnable done){
Fx.itemTransfer.at(x, y, 0, item.color, to);
if(done != null){
Time.run(Fx.itemTransfer.lifetime, done);
}
}
@Remote(variants = Variant.one)
public static void removeQueueBlock(int x, int y, boolean breaking){
player.removeRequest(x, y, breaking);
player.builder().removeBuild(x, y, breaking);
}
@Remote(targets = Loc.client, called = Loc.server)
public static void dropItem(Player player, float angle){
if(net.server() && player.item().amount <= 0){
public static void dropItem(Playerc player, float angle){
if(net.server() && player.unit().stack().amount <= 0){
throw new ValidateException(player, "Player cannot drop an item.");
}
Effects.effect(Fx.dropItem, Color.white, player.x, player.y, angle, player.item().item);
player.clearItem();
Fx.dropItem.at(player.x(), player.y(), angle, Color.white, player.unit().item());
player.unit().clearItem();
}
@Remote(targets = Loc.both, called = Loc.server, forward = true, unreliable = true)
public static void rotateBlock(Player player, Tile tile, boolean direction){
public static void rotateBlock(Playerc player, Tile tile, boolean direction){
if(net.server() && (!Units.canInteract(player, tile) ||
!netServer.admins.allowAction(player, ActionType.rotate, tile, action -> action.rotation = Mathf.mod(tile.rotation() + Mathf.sign(direction), 4)))){
throw new ValidateException(player, "Player cannot rotate a block.");
@@ -98,61 +125,51 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
@Remote(targets = Loc.both, forward = true, called = Loc.server)
public static void transferInventory(Player player, Tile tile){
if(player == null || player.timer == null) return;
if(net.server() && (player.item().amount <= 0 || player.isTransferring|| !Units.canInteract(player, tile) ||
public static void transferInventory(Playerc player, Tile tile){
if(player == null) return;
if(net.server() && (player.unit().stack().amount <= 0 || !Units.canInteract(player, tile) ||
!netServer.admins.allowAction(player, ActionType.depositItem, tile, action -> {
action.itemAmount = player.item().amount;
action.item = player.item().item;
action.itemAmount = player.unit().stack().amount;
action.item = player.unit().item();
}))){
throw new ValidateException(player, "Player cannot transfer an item.");
}
if(tile.entity == null) return;
player.isTransferring = true;
Item item = player.item().item;
int amount = player.item().amount;
int accepted = tile.block().acceptStack(item, amount, tile, player);
player.item().amount -= accepted;
Item item = player.unit().item();
int amount = player.unit().stack().amount;
int accepted = tile.block().acceptStack(item, amount, tile, player.unit());
player.unit().stack().amount -= accepted;
int sent = Mathf.clamp(accepted / 4, 1, 8);
int removed = accepted / sent;
int[] remaining = {accepted, accepted};
Block block = tile.block();
Core.app.post(() -> Events.fire(new DepositEvent(tile, player, item, accepted)));
for(int i = 0; i < sent; i++){
boolean end = i == sent - 1;
Time.run(i * 3, () -> {
tile.block().getStackOffset(item, tile, stackTrns);
tile.block().getStackOffset(item, tile, stackTrns);
ItemTransfer.create(item,
player.x + Angles.trnsx(player.rotation + 180f, backTrns), player.y + Angles.trnsy(player.rotation + 180f, backTrns),
new Vec2(tile.drawx() + stackTrns.x, tile.drawy() + stackTrns.y), () -> {
if(tile.block() != block || tile.entity == null || tile.entity.items == null) return;
createItemTransfer(item, player.x() + Angles.trnsx(player.unit().rotation() + 180f, backTrns), player.y() + Angles.trnsy(player.unit().rotation() + 180f, backTrns),
new Vec2(tile.drawx() + stackTrns.x, tile.drawy() + stackTrns.y), () -> {
if(tile.block() != block || tile.entity == null || tile.entity.items() == null) return;
tile.block().handleStack(item, removed, tile, player);
remaining[1] -= removed;
if(end && remaining[1] > 0){
tile.block().handleStack(item, remaining[1], tile, player);
}
});
remaining[0] -= removed;
if(end){
player.isTransferring = false;
}
tile.block().handleStack(item, accepted, tile, player.unit());
});
}
}
@Remote(targets = Loc.both, called = Loc.server, forward = true)
public static void onTileTapped(Playerc player, Tile tile){
if(tile == null || player == null) return;
if(net.server() && (!Units.canInteract(player, tile) ||
!netServer.admins.allowAction(player, ActionType.tapTile, tile, action -> {}))) throw new ValidateException(player, "Player cannot tap a tile.");
tile.block().tapped(tile, player);
Core.app.post(() -> Events.fire(new TapEvent(tile, player)));
}
@Remote(targets = Loc.both, called = Loc.both, forward = true)
public static void onTileConfig(Player player, Tile tile, @Nullable Object value){
public static void onTileConfig(Playerc player, Tile tile, @Nullable Object value){
if(tile == null) return;
if(net.server() && (!Units.canInteract(player, tile) ||
!netServer.admins.allowAction(player, ActionType.configure, tile, action -> action.config = value))) throw new ValidateException(player, "Player cannot configure a tile.");
@@ -162,7 +179,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public Eachable<BuildRequest> allRequests(){
return cons -> {
for(BuildRequest request : player.buildQueue()) cons.get(request);
for(BuildRequest request : player.builder().requests()) cons.get(request);
for(BuildRequest request : selectRequests) cons.get(request);
for(BuildRequest request : lineRequests) cons.get(request);
};
@@ -173,7 +190,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
public void update(){
player.typing(ui.chatfrag.shown());
}
public float getMouseX(){
@@ -238,26 +255,17 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
public void useSchematic(Schematic schem){
selectRequests.addAll(schematics.toRequests(schem, world.toTile(player.x), world.toTile(player.y)));
selectRequests.addAll(schematics.toRequests(schem, player.tileX(), player.tileY()));
}
protected void showSchematicSave(){
if(lastSchematic == null) return;
ui.showTextInput("$schematic.add", "$name", "", text -> {
Schematic replacement = schematics.all().find(s -> s.name().equals(text));
if(replacement != null){
ui.showConfirm("$confirm", "$schematic.replace", () -> {
schematics.overwrite(replacement, lastSchematic);
ui.showInfoFade("$schematic.saved");
ui.schematics.showInfo(replacement);
});
}else{
lastSchematic.tags.put("name", text);
schematics.add(lastSchematic);
ui.showInfoFade("$schematic.saved");
ui.schematics.showInfo(lastSchematic);
}
lastSchematic.tags.put("name", text);
schematics.add(lastSchematic);
ui.showInfoFade("$schematic.saved");
ui.schematics.showInfo(lastSchematic);
});
}
@@ -364,7 +372,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
return r2.overlaps(r1);
};
for(BuildRequest req : player.buildQueue()){
for(BuildRequest req : player.builder().requests()){
if(test.get(req)) return req;
}
@@ -393,7 +401,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
Draw.color(Pal.remove);
Lines.stroke(1f);
for(BuildRequest req : player.buildQueue()){
for(BuildRequest req : player.builder().requests()){
if(req.breaking) continue;
if(req.bounds(Tmp.r2).overlaps(Tmp.r1)){
drawBreaking(req);
@@ -407,7 +415,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
}
for(BrokenBlock req : player.getTeam().data().brokenBlocks){
for(BrokenBlock req : player.team().data().brokenBlocks){
Block block = content.block(req.block);
if(block.bounds(req.x, req.y, Tmp.r2).overlaps(Tmp.r1)){
drawSelected(req.x, req.y, content.block(req.block), Pal.remove);
@@ -454,7 +462,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
if(copy.hasConfig && copy.block.posConfig){
copy.config = Pos.get(Pos.x(copy.config) + copy.x - copy.originalX, Pos.y(copy.config) + copy.y - copy.originalY);
}
player.addBuildRequest(copy);
player.builder().addBuild(copy);
}
}
}
@@ -498,7 +506,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
//remove build requests
Tmp.r1.set(result.x * tilesize, result.y * tilesize, (result.x2 - result.x) * tilesize, (result.y2 - result.y) * tilesize);
Iterator<BuildRequest> it = player.buildQueue().iterator();
Iterator<BuildRequest> it = player.builder().requests().iterator();
while(it.hasNext()){
BuildRequest req = it.next();
if(!req.breaking && req.bounds(Tmp.r2).overlaps(Tmp.r1)){
@@ -515,7 +523,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
//remove blocks to rebuild
Iterator<BrokenBlock> broken = state.teams.get(player.getTeam()).brokenBlocks.iterator();
Iterator<BrokenBlock> broken = state.teams.get(player.team()).brokenBlocks.iterator();
while(broken.hasNext()){
BrokenBlock req = broken.next();
Block block = content.block(req.block);
@@ -555,7 +563,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
boolean consumed = false, showedInventory = false;
//check if tapped block is configurable
if(tile.block().configurable && tile.interactable(player.getTeam())){
if(tile.block().configurable && tile.interactable(player.team())){
consumed = true;
if(((!frag.config.isShown() && tile.block().shouldShowConfigure(tile, player)) //if the config fragment is hidden, show
//alternatively, the current selected block can 'agree' to switch config tiles
@@ -577,15 +585,15 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
//call tapped event
if(!consumed && tile.interactable(player.getTeam())){
if(!consumed && tile.interactable(player.team())){
Call.onTileConfig(player, tile, null);
}
//consume tap event if necessary
if(tile.interactable(player.getTeam()) && tile.block().consumesTap){
if(tile.interactable(player.team()) && tile.block().consumesTap){
consumed = true;
}else if(tile.interactable(player.getTeam()) && tile.block().synthetic() && !consumed){
if(tile.block().hasItems && tile.entity.items.total() > 0){
}else if(tile.interactable(player.team()) && tile.block().synthetic() && !consumed){
if(tile.block().hasItems && tile.entity.items().total() > 0){
frag.inv.showFor(tile);
consumed = true;
showedInventory = true;
@@ -609,14 +617,14 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
boolean canTapPlayer(float x, float y){
return Mathf.dst(x, y, player.x, player.y) <= playerSelectRange && player.item().amount > 0;
return player.within(x, y, playerSelectRange) && player.unit().stack().amount > 0;
}
/** Tries to begin mining a tile, returns true if successful. */
boolean tryBeginMine(Tile tile){
if(canMine(tile)){
//if a block is clicked twice, reset it
player.setMineTile(player.getMineTile() == tile ? null : tile);
player.miner().mineTile(player.miner().mineTile() == tile ? null : tile);
return true;
}
return false;
@@ -624,10 +632,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
boolean canMine(Tile tile){
return !Core.scene.hasMouse()
&& tile.drop() != null && tile.drop().hardness <= player.mech.drillPower
&& tile.drop() != null && player.miner().canMine(tile.drop())
&& !(tile.floor().playerUnmineable && tile.overlay().itemDrop == null)
&& player.acceptsItem(tile.drop())
&& tile.block() == Blocks.air && player.dst(tile.worldx(), tile.worldy()) <= Player.mineDistance;
&& player.unit().acceptsItem(tile.drop())
&& tile.block() == Blocks.air && player.dst(tile.worldx(), tile.worldy()) <= miningRange;
}
/** Returns the tile at the specified MOUSE coordinates. */
@@ -694,7 +702,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
public void add(){
Core.input.addProcessor(detector = new GestureDetector(20, 0.5f, 0.4f, 0.15f, this));
Core.input.getInputProcessors().remove(i -> i instanceof InputHandler || (i instanceof GestureDetector && ((GestureDetector)i).getListener() instanceof InputHandler));
Core.input.addProcessor(detector = new GestureDetector(20, 0.5f, 0.3f, 0.15f, this));
Core.input.addProcessor(this);
if(Core.scene != null){
Table table = (Table)Core.scene.find("inputTable");
@@ -711,10 +720,6 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
frag.add();
}
if(player != null){
player.isBuilding = true;
}
}
public boolean canShoot(){
@@ -730,16 +735,16 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
public void tryDropItems(Tile tile, float x, float y){
if(!droppingItem || player.item().amount <= 0 || canTapPlayer(x, y) || state.isPaused() ){
if(!droppingItem || player.unit().stack().amount <= 0 || canTapPlayer(x, y) || state.isPaused() ){
droppingItem = false;
return;
}
droppingItem = false;
ItemStack stack = player.item();
ItemStack stack = player.unit().stack();
if(tile.block().acceptStack(stack.item, stack.amount, tile, player) > 0 && tile.interactable(player.getTeam()) && tile.block().hasItems && player.item().amount > 0 && !player.isTransferring && tile.interactable(player.getTeam())){
if(tile.block().acceptStack(stack.item, stack.amount, tile, player.unit()) > 0 && tile.interactable(player.team()) && tile.block().hasItems && player.unit().stack().amount > 0 && tile.interactable(player.team())){
Call.transferInventory(player, tile);
}else{
Call.dropItem(player.angleTo(x, y));
@@ -763,7 +768,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
public boolean validPlace(int x, int y, Block type, int rotation, BuildRequest ignore){
for(BuildRequest req : player.buildQueue()){
for(BuildRequest req : player.builder().requests()){
if(req != ignore
&& !req.breaking
&& req.block.bounds(req.x, req.y, Tmp.r1).overlaps(type.bounds(x, y, Tmp.r2))
@@ -771,24 +776,24 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
return false;
}
}
return Build.validPlace(player.getTeam(), x, y, type, rotation);
return Build.validPlace(player.team(), x, y, type, rotation);
}
public boolean validBreak(int x, int y){
return Build.validBreak(player.getTeam(), x, y);
return Build.validBreak(player.team(), x, y);
}
public void placeBlock(int x, int y, Block block, int rotation){
BuildRequest req = getRequest(x, y);
if(req != null){
player.buildQueue().remove(req);
player.builder().requests().remove(req);
}
player.addBuildRequest(new BuildRequest(x, y, rotation, block));
player.builder().addBuild(new BuildRequest(x, y, rotation, block));
}
public void breakBlock(int x, int y){
Tile tile = world.ltile(x, y);
player.addBuildRequest(new BuildRequest(tile.x, tile.y));
player.builder().addBuild(new BuildRequest(tile.x, tile.y));
}
public void drawArrow(Block block, int x, int y, int rotation){
@@ -886,4 +891,192 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public int x, y, rotation;
public boolean last;
}
//TODO implement all of this!
/*
protected void updateKeyboard(){
Tile tile = world.tileWorld(x, y);
boolean canMove = !Core.scene.hasKeyboard() || ui.minimapfrag.shown();
isBoosting = Core.input.keyDown(Binding.dash) && !mech.flying;
//if player is in solid block
if(tile != null && tile.solid()){
isBoosting = true;
}
float speed = isBoosting && !mech.flying ? mech.boostSpeed : mech.speed;
if(mech.flying){
//prevent strafing backwards, have a penalty for doing so
float penalty = 0.2f; //when going 180 degrees backwards, reduce speed to 0.2x
speed *= Mathf.lerp(1f, penalty, Angles.angleDist(rotation, velocity.angle()) / 180f);
}
movement.setZero();
float xa = Core.input.axis(Binding.move_x);
float ya = Core.input.axis(Binding.move_y);
if(!(Core.scene.getKeyboardFocus() instanceof TextField)){
movement.y += ya * speed;
movement.x += xa * speed;
}
if(Core.input.keyDown(Binding.mouse_move)){
movement.x += Mathf.clamp((Core.input.mouseX() - Core.graphics.getWidth() / 2f) * 0.005f, -1, 1) * speed;
movement.y += Mathf.clamp((Core.input.mouseY() - Core.graphics.getHeight() / 2f) * 0.005f, -1, 1) * speed;
}
Vec2 vec = Core.input.mouseWorld(control.input.getMouseX(), control.input.getMouseY());
pointerX = vec.x;
pointerY = vec.y;
updateShooting();
movement.limit(speed).scl(Time.delta());
if(canMove){
velocity.add(movement.x, movement.y);
}else{
isShooting = false;
}
float prex = x, prey = y;
updateVelocityStatus();
moved = dst(prex, prey) > 0.001f;
if(canMove){
float baseLerp = mech.getRotationAlpha(this);
if(!isShooting() || !mech.faceTarget){
if(!movement.isZero()){
rotation = Mathf.slerpDelta(rotation, mech.flying ? velocity.angle() : movement.angle(), 0.13f * baseLerp);
}
}else{
float angle = control.input.mouseAngle(x, y);
this.rotation = Mathf.slerpDelta(this.rotation, angle, 0.1f * baseLerp);
}
}
}
protected void updateShooting(){
if(!state.isEditor() && isShooting() && mech.canShoot(this)){
weapons.update(this);
//if(!mech.turnCursor){
//shoot forward ignoring cursor
//mech.weapon.update(this, x + Angles.trnsx(rotation, mech.weapon.targetDistance), y + Angles.trnsy(rotation, mech.weapon.targetDistance));
//}else{
//mech.weapon.update(this, pointerX, pointerY);
//}
}
}
protected void updateTouch(){
if(Units.invalidateTarget(target, this) &&
!(target instanceof Tilec && ((Tilec)target).damaged() && target.isValid() && target.team() == team && mech.canHeal && dst(target) < mech.range && !(((Tilec)target).block instanceof BuildBlock))){
target = null;
}
if(state.isEditor()){
target = null;
}
float targetX = Core.camera.position.x, targetY = Core.camera.position.y;
float attractDst = 15f;
float speed = isBoosting && !mech.flying ? mech.boostSpeed : mech.speed;
if(moveTarget != null && !moveTarget.dead()){
targetX = moveTarget.getX();
targetY = moveTarget.getY();
boolean tapping = moveTarget instanceof Tilec && moveTarget.team() == team;
attractDst = 0f;
if(tapping){
velocity.setAngle(angleTo(moveTarget));
}
if(dst(moveTarget) <= 2f * Time.delta()){
if(tapping && !dead()){
Tile tile = ((Tilec)moveTarget).tile;
tile.block().tapped(tile, this);
}
moveTarget = null;
}
}else{
moveTarget = null;
}
movement.set((targetX - x) / Time.delta(), (targetY - y) / Time.delta()).limit(speed);
movement.setAngle(Mathf.slerp(movement.angle(), velocity.angle(), 0.05f));
if(dst(targetX, targetY) < attractDst){
movement.setZero();
}
float expansion = 3f;
hitbox(rect);
rect.x -= expansion;
rect.y -= expansion;
rect.width += expansion * 2f;
rect.height += expansion * 2f;
isBoosting = collisions.overlapsTile(rect) || dst(targetX, targetY) > 85f;
velocity.add(movement.scl(Time.delta()));
if(velocity.len() <= 0.2f && mech.flying){
rotation += Mathf.sin(Time.time() + id * 99, 10f, 1f);
}else if(target == null){
rotation = Mathf.slerpDelta(rotation, velocity.angle(), velocity.len() / 10f);
}
float lx = x, ly = y;
updateVelocityStatus();
moved = dst(lx, ly) > 0.001f;
if(mech.flying){
//hovering effect
x += Mathf.sin(Time.time() + id * 999, 25f, 0.08f);
y += Mathf.cos(Time.time() + id * 999, 25f, 0.08f);
}
//update shooting if not building, not mining and there's ammo left
if(!isBuilding() && mineTile() == null){
//autofire
if(target == null){
isShooting = false;
if(Core.settings.getBool("autotarget")){
target = Units.closestTarget(team, x, y, mech.range, u -> u.team() != Team.derelict, u -> u.team() != Team.derelict);
if(mech.canHeal && target == null){
target = Geometry.findClosest(x, y, indexer.getDamaged(Team.sharded));
if(target != null && dst(target) > mech.range){
target = null;
}else if(target != null){
target = ((Tile)target).entity;
}
}
if(target != null){
mineTile(null);
}
}
}else if(target.isValid() || (target instanceof Tilec && ((Tilec)target).damaged() && target.team() == team && mech.canHeal && dst(target) < mech.range)){
//rotate toward and shoot the target
if(mech.faceTarget){
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f);
}
Vec2 intercept = Predict.intercept(this, target, getWeapon().bullet.speed);
pointerX = intercept.x;
pointerY = intercept.y;
updateShooting();
isShooting = true;
}
}
}
*/
}

View File

@@ -16,12 +16,10 @@ import mindustry.*;
import mindustry.content.*;
import mindustry.core.GameState.*;
import mindustry.entities.*;
import mindustry.entities.traits.BuilderTrait.*;
import mindustry.entities.traits.*;
import mindustry.entities.type.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.ui.*;
import mindustry.world.*;
@@ -46,7 +44,7 @@ public class MobileInput extends InputHandler implements GestureListener{
private float lineScale;
/** Animation data for crosshair. */
private float crosshairScale;
private TargetTrait lastTarget;
private Teamc lastTarget;
/** Used for shifting build requests. */
private float shiftDeltaX, shiftDeltaY;
@@ -65,26 +63,29 @@ public class MobileInput extends InputHandler implements GestureListener{
/** Down tracking for panning.*/
private boolean down = false;
private Teamc target;
//region utility methods
/** Check and assign targets for a specific position. */
void checkTargets(float x, float y){
Unit unit = Units.closestEnemy(player.getTeam(), x, y, 20f, u -> !u.isDead());
Unitc unit = Units.closestEnemy(player.team(), x, y, 20f, u -> !u.dead());
if(unit != null){
player.setMineTile(null);
player.target = unit;
player.miner().mineTile(null);
target = unit;
}else{
Tile tile = world.ltileWorld(x, y);
if(tile != null && tile.synthetic() && player.getTeam().isEnemy(tile.getTeam())){
TileEntity entity = tile.entity;
player.setMineTile(null);
player.target = entity;
}else if(tile != null && player.mech.canHeal && tile.entity != null && tile.getTeam() == player.getTeam() && tile.entity.damaged()){
player.setMineTile(null);
player.target = tile.entity;
}
if(tile != null && tile.synthetic() && player.team().isEnemy(tile.team())){
Tilec entity = tile.entity;
player.miner().mineTile(null);
target = entity;
//TODO implement healing
}//else if(tile != null && player.unit().canHeal && tile.entity != null && tile.team() == player.team() && tile.entity.damaged()){
/// player.miner().mineTile(null);
// target = tile.entity;
// }
}
}
@@ -111,7 +112,7 @@ public class MobileInput extends InputHandler implements GestureListener{
}
}
for(BuildRequest req : player.buildQueue()){
for(BuildRequest req : player.builder().requests()){
Tile other = world.tile(req.x, req.y);
if(other == null || req.breaking) continue;
@@ -156,7 +157,7 @@ public class MobileInput extends InputHandler implements GestureListener{
}
void removeRequest(BuildRequest request){
selectRequests.removeValue(request, true);
selectRequests.remove(request, true);
if(!request.breaking){
removals.add(request);
}
@@ -179,19 +180,19 @@ public class MobileInput extends InputHandler implements GestureListener{
table.row();
table.left().margin(0f).defaults().size(48f);
table.addImageButton(Icon.breakSmall, Styles.clearTogglePartiali, () -> {
table.addImageButton(Icon.hammer, Styles.clearTogglePartiali, () -> {
mode = mode == breaking ? block == null ? none : placing : breaking;
lastBlock = block;
}).update(l -> l.setChecked(mode == breaking)).name("breakmode");
//diagonal swap button
table.addImageButton(Icon.diagonalSmall, Styles.clearTogglePartiali, () -> {
table.addImageButton(Icon.diagonal, Styles.clearTogglePartiali, () -> {
Core.settings.put("swapdiagonal", !Core.settings.getBool("swapdiagonal"));
Core.settings.save();
}).update(l -> l.setChecked(Core.settings.getBool("swapdiagonal")));
//rotate button
table.addImageButton(Icon.arrowSmall, Styles.clearTogglePartiali, () -> {
table.addImageButton(Icon.right, Styles.clearTogglePartiali, () -> {
if(block != null && block.rotate){
rotation = Mathf.mod(rotation + 1, 4);
}else{
@@ -205,12 +206,12 @@ public class MobileInput extends InputHandler implements GestureListener{
boolean arrow = block != null && block.rotate;
i.getImage().setRotationOrigin(!arrow ? 0 : rotation * 90, Align.center);
i.getStyle().imageUp = arrow ? Icon.arrowSmall : Icon.pasteSmall;
i.getStyle().imageUp = arrow ? Icon.right : Icon.paste;
i.setChecked(!arrow && schematicMode);
});
//confirm button
table.addImageButton(Icon.checkSmall, Styles.clearPartiali, () -> {
table.addImageButton(Icon.ok, Styles.clearPartiali, () -> {
for(BuildRequest request : selectRequests){
Tile tile = request.tile();
@@ -226,10 +227,10 @@ public class MobileInput extends InputHandler implements GestureListener{
}
if(other == null){
player.addBuildRequest(copy);
player.builder().addBuild(copy);
}else if(!other.breaking && other.x == request.x && other.y == request.y && other.block.size == request.block.size){
player.buildQueue().remove(other);
player.addBuildRequest(copy);
player.builder().requests().remove(other);
player.builder().addBuild(copy);
}
}
@@ -252,13 +253,13 @@ public class MobileInput extends InputHandler implements GestureListener{
Boolp schem = () -> lastSchematic != null && !selectRequests.isEmpty();
group.fill(t -> {
t.bottom().left().visible(() -> (player.isBuilding() || block != null || mode == breaking || !selectRequests.isEmpty()) && !schem.get());
t.addImageTextButton("$cancel", Icon.cancelSmall, () -> {
player.clearBuilding();
t.bottom().left().visible(() -> (player.builder().isBuilding() || block != null || mode == breaking || !selectRequests.isEmpty()) && !schem.get());
t.addImageTextButton("$cancel", Icon.cancel, () -> {
player.builder().clearBuilding();
selectRequests.clear();
mode = none;
block = null;
}).width(155f);
}).width(155f).margin(12f);
});
group.fill(t -> {
@@ -269,15 +270,15 @@ public class MobileInput extends InputHandler implements GestureListener{
ImageButtonStyle style = Styles.clearPartiali;
b.addImageButton(Icon.floppySmall, style, this::showSchematicSave).disabled(f -> lastSchematic == null || lastSchematic.file != null);
b.addImageButton(Icon.cancelSmall, style, () -> {
b.addImageButton(Icon.save, style, this::showSchematicSave).disabled(f -> lastSchematic == null || lastSchematic.file != null);
b.addImageButton(Icon.cancel, style, () -> {
selectRequests.clear();
});
b.row();
b.addImageButton(Icon.flipSmall, style, () -> flipRequests(selectRequests, true));
b.addImageButton(Icon.flipSmall, style, () -> flipRequests(selectRequests, false)).update(i -> i.getImage().setRotationOrigin(90f, Align.center));
b.addImageButton(Icon.flipX, style, () -> flipRequests(selectRequests, true));
b.addImageButton(Icon.flipY, style, () -> flipRequests(selectRequests, false));
b.row();
b.addImageButton(Icon.rotateSmall, style, () -> rotateRequests(selectRequests, 1));
b.addImageButton(Icon.rotate, style, () -> rotateRequests(selectRequests, 1));
}).margin(4f);
});
@@ -377,8 +378,6 @@ public class MobileInput extends InputHandler implements GestureListener{
}
}
TargetTrait target = player.target;
//draw targeting crosshair
if(target != null && !state.isEditor()){
if(target != lastTarget){
@@ -433,7 +432,7 @@ public class MobileInput extends InputHandler implements GestureListener{
@Override
public void useSchematic(Schematic schem){
selectRequests.clear();
selectRequests.addAll(schematics.toRequests(schem, world.toTile(player.x), world.toTile(player.y)));
selectRequests.addAll(schematics.toRequests(schem, player.tileX(), player.tileY()));
lastSchematic = schem;
}
@@ -443,7 +442,7 @@ public class MobileInput extends InputHandler implements GestureListener{
down = true;
if(player.isDead()) return false;
if(player.dead()) return false;
//get tile on cursor
Tile cursor = tileAt(screenX, screenY);
@@ -469,7 +468,7 @@ public class MobileInput extends InputHandler implements GestureListener{
lastLineY = tileY;
}else if(!tryTapPlayer(worldx, worldy) && Core.settings.getBool("keyboard")){
//shoot on touch down when in keyboard mode
player.isShooting = true;
isShooting = true;
}
}
@@ -520,7 +519,7 @@ public class MobileInput extends InputHandler implements GestureListener{
@Override
public boolean longPress(float x, float y){
if(state.is(State.menu) || mode == none || player.isDead()) return false;
if(state.is(State.menu) || mode == none || player.dead()) return false;
//get tile on cursor
Tile cursor = tileAt(x, y);
@@ -537,10 +536,10 @@ public class MobileInput extends InputHandler implements GestureListener{
lineMode = true;
if(mode == breaking){
Effects.effect(Fx.tapBlock, cursor.worldx(), cursor.worldy(), 1f);
Fx.tapBlock.at(cursor.worldx(), cursor.worldy(), 1f);
}else if(block != null){
updateLine(lineStartX, lineStartY, cursor.x, cursor.y);
Effects.effect(Fx.tapBlock, cursor.worldx() + block.offset(), cursor.worldy() + block.offset(), block.size);
Fx.tapBlock.at(cursor.worldx() + block.offset(), cursor.worldy() + block.offset(), block.size);
}
return false;
@@ -579,13 +578,15 @@ public class MobileInput extends InputHandler implements GestureListener{
@Override
public void update(){
super.update();
if(state.is(State.menu) ){
selectRequests.clear();
removals.clear();
mode = none;
}
if(player.isDead()){
if(player.dead()){
mode = none;
}
@@ -602,11 +603,11 @@ public class MobileInput extends InputHandler implements GestureListener{
if(Core.settings.getBool("keyboard")){
if(Core.input.keyRelease(Binding.select)){
player.isShooting = false;
isShooting = false;
}
if(player.isShooting && !canShoot()){
player.isShooting = false;
if(isShooting && !canShoot()){
isShooting = false;
}
}