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:
@@ -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);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user