Files
Mindustry/core/src/mindustry/input/DesktopInput.java

637 lines
24 KiB
Java
Raw Normal View History

2019-12-25 01:39:38 -05:00
package mindustry.input;
2017-05-03 00:09:48 -04:00
2019-12-25 01:39:38 -05:00
import arc.*;
import arc.Graphics.*;
import arc.Graphics.Cursor.*;
import arc.graphics.g2d.*;
import arc.math.*;
2020-02-08 14:48:04 -05:00
import arc.math.geom.*;
2019-12-25 01:39:38 -05:00
import arc.scene.*;
import arc.scene.event.*;
import arc.scene.ui.*;
import arc.scene.ui.layout.*;
import arc.util.ArcAnnotate.*;
2019-12-29 00:09:46 -05:00
import arc.util.*;
2019-12-25 01:39:38 -05:00
import mindustry.*;
2020-02-07 11:46:10 -05:00
import mindustry.entities.*;
2020-02-02 23:38:16 -05:00
import mindustry.entities.units.*;
2019-12-25 01:39:38 -05:00
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.ui.*;
import mindustry.world.*;
2017-05-03 00:09:48 -04:00
2020-07-09 20:58:49 -04:00
import static arc.Core.*;
import static mindustry.Vars.net;
2019-12-25 01:39:38 -05:00
import static mindustry.Vars.*;
import static mindustry.input.PlaceMode.*;
public class DesktopInput extends InputHandler{
private Vec2 movement = new Vec2();
2019-04-08 09:03:18 -04:00
/** Current cursor type. */
2018-12-26 13:22:31 -05:00
private Cursor cursorType = SystemCursor.arrow;
2019-04-08 09:03:18 -04:00
/** Position where the player started dragging a line. */
2019-10-14 21:34:06 -04:00
private int selectX, selectY, schemX, schemY;
/** Last known line positions.*/
2019-10-18 00:41:30 -04:00
private int lastLineX, lastLineY, schematicX, schematicY;
2019-04-08 09:03:18 -04:00
/** Whether selecting mode is active. */
2018-05-30 13:43:49 -04:00
private PlaceMode mode;
2019-04-08 09:03:18 -04:00
/** Animation scale for line. */
private float selectScale;
2019-10-07 19:51:52 -04:00
/** Selected build request for movement. */
2020-06-15 12:00:32 -04:00
private @Nullable BuildPlan sreq;
2019-10-07 20:26:08 -04:00
/** Whether player is currently deleting removal requests. */
2020-05-20 18:48:04 -04:00
private boolean deleting = false, shouldShoot = false;
2019-03-19 15:26:30 -04:00
@Override
public void buildUI(Group group){
group.fill(t -> {
2020-06-29 15:58:48 -04:00
t.bottom();
t.visible(() -> {
t.getColor().a = Mathf.lerpDelta(t.getColor().a, player.builder().isBuilding() ? 1f : 0f, 0.15f);
return Core.settings.getBool("hints") && selectRequests.isEmpty() && t.getColor().a > 0.01f;
});
2019-10-23 16:48:55 -04:00
t.touchable(() -> t.getColor().a < 0.1f ? Touchable.disabled : Touchable.childrenOnly);
2019-10-07 20:26:08 -04:00
t.table(Styles.black6, b -> {
b.defaults().left();
2020-02-05 22:08:57 -05:00
b.label(() -> Core.bundle.format(!isBuilding ? "resumebuilding" : "pausebuilding", Core.keybinds.get(Binding.pause_building).key.toString())).style(Styles.outlineLabel);
2019-10-07 20:26:08 -04:00
b.row();
2019-11-14 18:48:12 -05:00
b.label(() -> Core.bundle.format("cancelbuilding", Core.keybinds.get(Binding.clear_building).key.toString())).style(Styles.outlineLabel);
2019-10-18 17:18:29 -04:00
b.row();
2019-11-14 18:48:12 -05:00
b.label(() -> Core.bundle.format("selectschematic", Core.keybinds.get(Binding.schematic_select).key.toString())).style(Styles.outlineLabel);
2019-10-07 20:26:08 -04:00
}).margin(10f);
});
2019-10-18 11:38:00 -04:00
group.fill(t -> {
2020-05-24 22:27:14 -04:00
t.visible(() -> Core.settings.getBool("hints") && lastSchematic != null && !selectRequests.isEmpty());
2019-10-18 11:38:00 -04:00
t.bottom();
t.table(Styles.black6, b -> {
b.defaults().left();
2019-11-14 18:48:12 -05:00
b.label( () -> Core.bundle.format("schematic.flip",
Core.keybinds.get(Binding.schematic_flip_x).key.toString(),
Core.keybinds.get(Binding.schematic_flip_y).key.toString())).style(Styles.outlineLabel);
2019-10-18 11:38:00 -04:00
b.row();
b.table(a -> {
2020-04-17 11:26:59 -04:00
a.button("$schematic.add", Icon.save, this::showSchematicSave).colspan(2).size(250f, 50f).disabled(f -> lastSchematic == null || lastSchematic.file != null);
2019-10-18 11:38:00 -04:00
});
}).margin(6f);
});
2020-05-24 22:27:14 -04:00
group.fill(t -> {
t.visible(() -> Core.settings.getBool("hints") && !player.dead() && !player.unit().spawnedByCore());
t.bottom();
t.table(Styles.black6, b -> {
b.defaults().left();
b.label(() -> Core.bundle.format("respawn", Core.keybinds.get(Binding.respawn).key.toString())).style(Styles.outlineLabel);
}).margin(6f);
});
}
@Override
2019-10-06 23:03:02 -04:00
public void drawTop(){
Lines.stroke(1f);
2018-12-22 22:17:28 -05:00
int cursorX = tileX(Core.input.mouseX());
int cursorY = tileY(Core.input.mouseY());
//draw break selection
if(mode == breaking){
2019-10-18 14:38:43 -04:00
drawBreakSelection(selectX, selectY, cursorX, cursorY);
}
if(Core.input.keyDown(Binding.schematic_select) && !Core.scene.hasKeyboard()){
drawSelection(schemX, schemY, cursorX, cursorY, Vars.maxSchematicSize);
}
Draw.reset();
}
@Override
public void drawBottom(){
int cursorX = tileX(Core.input.mouseX());
int cursorY = tileY(Core.input.mouseY());
//draw request being moved
if(sreq != null){
boolean valid = validPlace(sreq.x, sreq.y, sreq.block, sreq.rotation, sreq);
if(sreq.block.rotate){
drawArrow(sreq.block, sreq.x, sreq.y, sreq.rotation, valid);
2018-05-30 12:40:51 -04:00
}
sreq.block.drawRequest(sreq, allRequests(), valid);
drawSelected(sreq.x, sreq.y, sreq.block, getRequest(sreq.x, sreq.y, sreq.block.size, sreq) != null ? Pal.remove : Pal.accent);
2018-05-30 12:40:51 -04:00
}
2018-04-19 21:57:55 -04:00
//draw hover request
2019-10-07 19:51:52 -04:00
if(mode == none && !isPlacing()){
2020-06-15 12:00:32 -04:00
BuildPlan req = getRequest(cursorX, cursorY);
2019-10-07 19:51:52 -04:00
if(req != null){
drawSelected(req.x, req.y, req.breaking ? req.tile().block() : req.block, Pal.accent);
}
}
2019-10-18 00:41:30 -04:00
//draw schematic requests
2020-06-15 12:00:32 -04:00
for(BuildPlan request : selectRequests){
2019-10-18 00:41:30 -04:00
request.animScale = 1f;
drawRequest(request);
}
2020-06-15 12:00:32 -04:00
for(BuildPlan request : selectRequests){
2020-03-04 19:21:40 -05:00
drawOverRequest(request);
}
2020-05-11 23:40:23 -04:00
if(player.isBuilder()){
//draw things that may be placed soon
if(mode == placing && block != null){
for(int i = 0; i < lineRequests.size; i++){
2020-06-15 12:00:32 -04:00
BuildPlan req = lineRequests.get(i);
2020-05-11 23:40:23 -04:00
if(i == lineRequests.size - 1 && req.block.rotate){
drawArrow(block, req.x, req.y, req.rotation);
}
drawRequest(lineRequests.get(i));
}
2020-05-11 23:40:23 -04:00
}else if(isPlacing()){
if(block.rotate){
drawArrow(block, cursorX, cursorY, rotation);
}
Draw.color();
drawRequest(cursorX, cursorY, block, rotation);
block.drawPlace(cursorX, cursorY, rotation, validPlace(cursorX, cursorY, block, rotation));
2020-05-03 12:08:11 -04:00
2020-05-11 23:40:23 -04:00
if(block.saveConfig && block.lastConfig != null){
brequest.set(cursorX, cursorY, rotation, block);
brequest.config = block.lastConfig;
block.drawRequestConfig(brequest, allRequests());
brequest.config = null;
2020-05-11 23:40:23 -04:00
}
2020-05-03 12:08:11 -04:00
2020-05-11 23:40:23 -04:00
}
2019-10-14 21:34:06 -04:00
}
2018-05-30 12:40:51 -04:00
Draw.reset();
}
2018-07-12 20:37:14 -04:00
@Override
public void update(){
2020-02-04 18:00:32 -05:00
super.update();
2019-09-07 14:11:50 -04:00
if(net.active() && Core.input.keyTap(Binding.player_list)){
2018-06-25 19:25:26 -04:00
ui.listfrag.toggle();
}
2020-06-22 13:40:04 -04:00
//TODO awful UI state checking code
2020-02-07 11:46:10 -05:00
if((player.dead() || state.isPaused()) && !ui.chatfrag.shown()){
2020-06-19 19:31:14 -04:00
if(!(scene.getKeyboardFocus() instanceof TextField) && !scene.hasDialog()){
2020-05-05 23:01:12 -04:00
//move camera around
2020-05-13 17:04:59 -04:00
float camSpeed = !Core.input.keyDown(Binding.boost) ? 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));
2020-05-05 23:01:12 -04:00
if(Core.input.keyDown(Binding.mouse_move)){
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;
}
2019-12-29 17:56:10 -05:00
}
2020-02-07 11:46:10 -05:00
}else if(!player.dead()){
2020-06-22 13:40:04 -04:00
Core.camera.position.lerpDelta(player, Core.settings.getBool("smoothcamera") ? 0.08f : 1f);
2020-02-07 11:46:10 -05:00
}
2020-05-20 18:48:04 -04:00
shouldShoot = true;
if(!scene.hasMouse()){
2020-04-11 11:34:51 -04:00
if(Core.input.keyDown(Binding.control) && Core.input.keyTap(Binding.select)){
2020-06-26 14:27:26 -04:00
Unit on = selectedUnit();
2020-04-11 11:34:51 -04:00
if(on != null){
Call.unitControl(player, on);
2020-05-20 18:48:04 -04:00
shouldShoot = false;
2020-02-07 11:46:10 -05:00
}
}
}
2020-02-08 14:48:04 -05:00
if(!player.dead() && !state.isPaused() && !(Core.scene.getKeyboardFocus() instanceof TextField)){
2020-02-07 18:55:53 -05:00
updateMovement(player.unit());
2020-06-02 22:09:41 -04:00
if(Core.input.keyDown(Binding.respawn) && !player.unit().spawnedByCore()){
Call.unitClear(player);
2020-06-02 22:09:41 -04:00
controlledType = null;
}
2019-12-29 00:09:46 -05:00
}
2018-12-22 22:17:28 -05:00
if(Core.input.keyRelease(Binding.select)){
2020-07-09 13:13:57 -04:00
player.shooting = false;
2018-08-30 16:46:41 -04:00
}
2020-03-08 21:53:19 -04:00
if(state.isGame() && Core.input.keyTap(Binding.minimap) && !scene.hasDialog() && !(scene.getKeyboardFocus() instanceof TextField)){
2019-12-29 17:56:10 -05:00
ui.minimapfrag.toggle();
}
2020-03-08 21:53:19 -04:00
if(state.isMenu() || Core.scene.hasDialog()) return;
2018-08-07 18:19:02 -04:00
//zoom camera
2020-02-07 18:55:53 -05:00
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()))){
2018-12-28 13:01:35 -05:00
renderer.scaleCamera(Core.input.axisTap(Binding.zoom));
2018-08-07 18:19:02 -04:00
}
if(player.dead()){
2019-03-18 23:09:03 -04:00
cursorType = SystemCursor.arrow;
return;
}
2018-08-30 16:46:41 -04:00
pollInput();
//deselect if not placing
2018-07-12 20:37:14 -04:00
if(!isPlacing() && mode == placing){
mode = none;
}
2020-07-09 13:13:57 -04:00
if(player.shooting && !canShoot()){
player.shooting = false;
}
2020-05-11 23:40:23 -04:00
if(isPlacing() && player.isBuilder()){
2018-12-26 13:22:31 -05:00
cursorType = SystemCursor.hand;
selectScale = Mathf.lerpDelta(selectScale, 1f, 0.2f);
}else{
2018-07-12 20:37:14 -04:00
selectScale = 0f;
}
if(!Core.input.keyDown(Binding.diagonal_placement) && Math.abs((int)Core.input.axisTap(Binding.rotate)) > 0){
2019-11-02 14:09:16 -04:00
rotation = Mathf.mod(rotation + (int)Core.input.axisTap(Binding.rotate), 4);
if(sreq != null){
sreq.rotation = Mathf.mod(sreq.rotation + (int)Core.input.axisTap(Binding.rotate), 4);
}
2019-10-07 19:51:52 -04:00
2019-10-18 14:38:43 -04:00
if(isPlacing() && mode == placing){
updateLine(selectX, selectY);
}else if(!selectRequests.isEmpty()){
2020-05-04 08:59:56 -04:00
rotateRequests(selectRequests, Mathf.sign(Core.input.axisTap(Binding.rotate)));
2019-10-18 14:38:43 -04:00
}
2019-10-06 17:30:11 -04:00
}
2018-06-02 00:46:40 -04:00
2018-12-22 22:17:28 -05:00
Tile cursor = tileAt(Core.input.mouseX(), Core.input.mouseY());
2019-03-18 23:09:03 -04:00
if(cursor != null){
2020-06-27 19:16:39 -04:00
if(cursor.build != null){
cursorType = cursor.build.getCursor();
2020-03-05 18:05:59 -05:00
}
2019-10-18 00:41:30 -04:00
if(isPlacing() || !selectRequests.isEmpty()){
2018-12-26 13:22:31 -05:00
cursorType = SystemCursor.hand;
}
if(!isPlacing() && canMine(cursor)){
2018-12-26 13:22:31 -05:00
cursorType = ui.drillCursor;
2018-06-02 21:45:07 -04:00
}
2019-10-07 19:51:52 -04:00
if(getRequest(cursor.x, cursor.y) != null && mode == none){
cursorType = SystemCursor.hand;
}
2018-12-22 22:17:28 -05:00
if(canTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y)){
2018-12-26 13:22:31 -05:00
cursorType = ui.unloadCursor;
}
2020-06-27 19:16:39 -04:00
if(cursor.build != null && 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.build, Core.input.axisTap(Binding.rotate) > 0);
}
}
2018-12-22 22:17:28 -05:00
if(!Core.scene.hasMouse()){
2018-12-26 13:22:31 -05:00
Core.graphics.cursor(cursorType);
2018-07-12 20:37:14 -04:00
}
2018-12-26 13:22:31 -05:00
cursorType = SystemCursor.arrow;
2018-07-12 20:37:14 -04:00
}
2019-10-18 00:41:30 -04:00
@Override
public void useSchematic(Schematic schem){
block = null;
schematicX = tileX(getMouseX());
schematicY = tileY(getMouseY());
selectRequests.clear();
2019-10-18 00:41:30 -04:00
selectRequests.addAll(schematics.toRequests(schem, schematicX, schematicY));
mode = none;
}
@Override
public boolean isBreaking(){
return mode == breaking;
}
2019-10-19 19:54:41 -04:00
@Override
public void buildPlacementUI(Table table){
2020-04-17 11:26:59 -04:00
table.image().color(Pal.gray).height(4f).colspan(4).growX();
2019-10-19 19:54:41 -04:00
table.row();
table.left().margin(0f).defaults().size(48f).left();
2020-04-17 11:26:59 -04:00
table.button(Icon.paste, Styles.clearPartiali, () -> {
2019-10-19 19:54:41 -04:00
ui.schematics.show();
});
2020-07-08 12:11:27 -04:00
table.button(Icon.tree, Styles.clearPartiali, () -> {
ui.research.show();
}).visible(() -> state.isCampaign());
table.button(Icon.map, Styles.clearPartiali, () -> {
ui.planet.show();
}).visible(() -> state.isCampaign());
table.button(Icon.up, Styles.clearPartiali, () -> {
ui.planet.show(state.getSector(), player.team().core());
}).visible(() -> state.isCampaign())
.disabled(b -> player.team().core() == null || !player.team().core().items.has(player.team().core().block.requirements));
2019-10-19 19:54:41 -04:00
}
2018-08-30 16:46:41 -04:00
void pollInput(){
2019-10-20 12:48:39 -04:00
if(scene.getKeyboardFocus() instanceof TextField) return;
2018-12-22 22:17:28 -05:00
Tile selected = tileAt(Core.input.mouseX(), Core.input.mouseY());
int cursorX = tileX(Core.input.mouseX());
int cursorY = tileY(Core.input.mouseY());
2019-10-14 21:34:06 -04:00
int rawCursorX = world.toTile(Core.input.mouseWorld().x), rawCursorY = world.toTile(Core.input.mouseWorld().y);
2017-05-03 00:09:48 -04:00
// automatically pause building if the current build queue is empty
2020-02-05 22:08:57 -05:00
if(Core.settings.getBool("buildautopause") && isBuilding && !player.builder().isBuilding()){
isBuilding = false;
buildWasAutoPaused = true;
}
2019-10-18 00:41:30 -04:00
if(!selectRequests.isEmpty()){
int shiftX = rawCursorX - schematicX, shiftY = rawCursorY - schematicY;
selectRequests.each(s -> {
s.x += shiftX;
s.y += shiftY;
});
schematicX += shiftX;
schematicY += shiftY;
}
2018-12-22 22:17:28 -05:00
if(Core.input.keyTap(Binding.deselect)){
2020-02-05 22:08:57 -05:00
player.miner().mineTile(null);
2018-09-24 22:56:48 -04:00
}
if(Core.input.keyTap(Binding.clear_building)){
2020-02-05 22:08:57 -05:00
player.builder().clearBuilding();
}
2019-12-07 14:10:39 -05:00
if(Core.input.keyTap(Binding.schematic_select) && !Core.scene.hasKeyboard()){
2019-10-14 21:34:06 -04:00
schemX = rawCursorX;
schemY = rawCursorY;
}
2019-12-07 14:10:39 -05:00
if(Core.input.keyTap(Binding.schematic_menu) && !Core.scene.hasKeyboard()){
2019-10-25 13:05:04 -04:00
if(ui.schematics.isShown()){
ui.schematics.hide();
}else{
ui.schematics.show();
ui.schematics.focusSearchField();
2019-10-25 13:05:04 -04:00
}
2019-10-19 21:09:59 -04:00
}
2019-12-27 01:22:50 -05:00
if(Core.input.keyTap(Binding.clear_building) || isPlacing()){
lastSchematic = null;
selectRequests.clear();
}
2019-12-07 14:10:39 -05:00
if(Core.input.keyRelease(Binding.schematic_select) && !Core.scene.hasKeyboard()){
2019-10-18 11:38:00 -04:00
lastSchematic = schematics.create(schemX, schemY, rawCursorX, rawCursorY);
useSchematic(lastSchematic);
if(selectRequests.isEmpty()){
lastSchematic = null;
}
2019-10-14 21:34:06 -04:00
}
2019-10-18 14:38:43 -04:00
if(!selectRequests.isEmpty()){
if(Core.input.keyTap(Binding.schematic_flip_x)){
flipRequests(selectRequests, true);
}
if(Core.input.keyTap(Binding.schematic_flip_y)){
flipRequests(selectRequests, false);
}
}
2019-10-07 19:51:52 -04:00
if(sreq != null){
float offset = ((sreq.block.size + 2) % 2) * tilesize / 2f;
float x = Core.input.mouseWorld().x + offset;
float y = Core.input.mouseWorld().y + offset;
sreq.x = (int)(x / tilesize);
sreq.y = (int)(y / tilesize);
}
if(block == null || mode != placing){
lineRequests.clear();
}
2019-10-07 20:26:08 -04:00
if(Core.input.keyTap(Binding.pause_building)){
2020-02-05 22:08:57 -05:00
isBuilding = !isBuilding;
buildWasAutoPaused = false;
2020-07-13 08:50:19 -04:00
if(isBuilding){
player.shooting = false;
}
2019-10-07 20:26:08 -04:00
}
if((cursorX != lastLineX || cursorY != lastLineY) && isPlacing() && mode == placing){
updateLine(selectX, selectY);
lastLineX = cursorX;
lastLineY = cursorY;
}
2018-12-22 22:17:28 -05:00
if(Core.input.keyTap(Binding.select) && !Core.scene.hasMouse()){
2020-06-15 12:00:32 -04:00
BuildPlan req = getRequest(cursorX, cursorY);
2019-10-07 19:51:52 -04:00
if(Core.input.keyDown(Binding.break_block)){
mode = none;
}else if(!selectRequests.isEmpty()){
2019-10-18 00:41:30 -04:00
flushRequests(selectRequests);
}else if(isPlacing()){
selectX = cursorX;
selectY = cursorY;
lastLineX = cursorX;
lastLineY = cursorY;
2018-09-29 20:49:19 -04:00
mode = placing;
updateLine(selectX, selectY);
2019-10-12 12:52:50 -04:00
}else if(req != null && !req.breaking && mode == none && !req.initialized){
2019-10-07 19:51:52 -04:00
sreq = req;
2019-10-07 20:26:08 -04:00
}else if(req != null && req.breaking){
deleting = true;
}else if(selected != null){
2018-09-29 20:49:19 -04:00
//only begin shooting if there's no cursor event
2020-07-13 08:50:19 -04:00
if(!tileTapped(selected.build) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && (player.builder().plans().size == 0 || !player.builder().updateBuilding()) && !droppingItem &&
2020-02-05 22:08:57 -05:00
!tryBeginMine(selected) && player.miner().mineTile() == null && !Core.scene.hasKeyboard()){
2020-07-09 13:13:57 -04:00
player.shooting = shouldShoot;
2018-09-29 20:49:19 -04:00
}
2019-12-07 14:10:39 -05:00
}else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine
2020-07-09 13:13:57 -04:00
player.shooting = shouldShoot;
2018-09-29 20:49:19 -04:00
}
}else if(Core.input.keyTap(Binding.deselect) && isPlacing()){
2019-01-20 13:49:53 -05:00
block = null;
2018-09-29 20:49:19 -04:00
mode = none;
}else if(Core.input.keyTap(Binding.deselect) && !selectRequests.isEmpty()){
selectRequests.clear();
lastSchematic = null;
2020-05-11 23:40:23 -04:00
}else if(Core.input.keyTap(Binding.break_block) && !Core.scene.hasMouse() && player.isBuilder()){
//is recalculated because setting the mode to breaking removes potential multiblock cursor offset
2019-10-07 20:26:08 -04:00
deleting = false;
2018-09-29 20:49:19 -04:00
mode = breaking;
2018-12-22 22:17:28 -05:00
selectX = tileX(Core.input.mouseX());
selectY = tileY(Core.input.mouseY());
}
2019-10-07 20:26:08 -04:00
if(Core.input.keyDown(Binding.select) && mode == none && !isPlacing() && deleting){
2020-06-15 12:00:32 -04:00
BuildPlan req = getRequest(cursorX, cursorY);
2019-10-07 20:26:08 -04:00
if(req != null && req.breaking){
2020-06-15 12:00:32 -04:00
player.builder().plans().remove(req);
2019-10-07 20:26:08 -04:00
}
}else{
deleting = false;
}
if(mode == placing && block != null){
2019-12-26 17:46:01 -05:00
if(!overrideLineRotation && !Core.input.keyDown(Binding.diagonal_placement) && (selectX != cursorX || selectY != cursorY) && ((int)Core.input.axisTap(Binding.rotate) != 0)){
rotation = ((int)((Angles.angle(selectX, selectY, cursorX, cursorY) + 45) / 90f)) % 4;
overrideLineRotation = true;
}
}else{
overrideLineRotation = false;
}
2019-03-18 23:09:03 -04:00
if(Core.input.keyRelease(Binding.break_block) || Core.input.keyRelease(Binding.select)){
2018-05-30 12:40:51 -04:00
2019-03-18 23:09:03 -04:00
if(mode == placing && block != null){ //touch up while placing, place everything in selection
flushRequests(lineRequests);
lineRequests.clear();
2019-08-08 17:03:45 -04:00
Events.fire(new LineConfirmEvent());
2018-08-30 16:46:41 -04:00
}else if(mode == breaking){ //touch up while breaking, break everything in selection
2019-10-07 17:17:01 -04:00
removeSelection(selectX, selectY, cursorX, cursorY);
2018-05-30 13:43:49 -04:00
}
2018-06-02 21:45:07 -04:00
2020-06-27 19:16:39 -04:00
tryDropItems(selected == null ? null : selected.build, Core.input.mouseWorld().x, Core.input.mouseWorld().y);
2019-10-07 19:51:52 -04:00
if(sreq != null){
if(getRequest(sreq.x, sreq.y, sreq.block.size, sreq) != null){
2020-06-15 12:00:32 -04:00
player.builder().plans().remove(sreq, true);
2019-10-07 19:51:52 -04:00
}
sreq = null;
}
2018-08-30 16:46:41 -04:00
mode = none;
}
2020-03-24 12:02:26 -04:00
if(Core.input.keyTap(Binding.toggle_block_status)){
2020-05-16 10:23:06 -04:00
Core.settings.put("blockstatus", !Core.settings.getBool("blockstatus"));
2020-03-24 12:02:26 -04:00
}
if(Core.input.keyTap(Binding.toggle_power_lines)){
if(Core.settings.getInt("lasersopacity") == 0){
Core.settings.put("lasersopacity", Core.settings.getInt("preferredlaseropacity", 100));
}else{
Core.settings.put("preferredlaseropacity", Core.settings.getInt("lasersopacity"));
Core.settings.put("lasersopacity", 0);
}
}
2019-03-18 23:09:03 -04:00
}
@Override
public boolean selectedBlock(){
return isPlacing() && mode != breaking;
}
@Override
2018-07-12 20:37:14 -04:00
public float getMouseX(){
return Core.input.mouseX();
}
@Override
2018-07-12 20:37:14 -04:00
public float getMouseY(){
return Core.input.mouseY();
}
@Override
2019-09-21 15:35:59 -04:00
public void updateState(){
2020-03-08 21:53:19 -04:00
if(state.isMenu()){
droppingItem = false;
2019-04-07 16:58:22 -04:00
mode = none;
block = null;
2019-10-07 19:51:52 -04:00
sreq = null;
2019-10-18 00:41:30 -04:00
selectRequests.clear();
}
}
2020-02-07 11:46:10 -05:00
2020-06-26 14:27:26 -04:00
protected void updateMovement(Unit unit){
2020-02-08 14:48:04 -05:00
boolean omni = !(unit instanceof WaterMovec);
boolean legs = unit.isGrounded();
2020-05-22 14:35:25 -04:00
float strafePenalty = legs ? 1f : Mathf.lerp(1f, unit.type().strafePenalty, Angles.angleDist(unit.vel().angle(), unit.rotation()) / 180f);
float speed = unit.type().speed * Mathf.lerp(1f, unit.type().canBoost ? unit.type().boostMultiplier : 1f, unit.elevation()) * strafePenalty;
2020-02-07 11:46:10 -05:00
float xa = Core.input.axis(Binding.move_x);
float ya = Core.input.axis(Binding.move_y);
2020-05-26 12:59:05 -04:00
boolean boosted = (unit instanceof Mechc && unit.isFlying());
2020-02-07 11:46:10 -05:00
movement.set(xa, ya).nor().scl(speed);
2020-07-11 22:41:26 -04:00
float mouseAngle = Angles.mouseAngle(unit.x, unit.y);
2020-07-09 13:13:57 -04:00
boolean aimCursor = omni && player.shooting && unit.type().hasWeapons() && unit.type().faceTarget && !boosted && unit.type().rotateShooting;
if(aimCursor){
unit.lookAt(mouseAngle);
}else{
2020-05-28 12:16:35 -04:00
if(unit.moving()){
2020-05-22 14:35:25 -04:00
unit.lookAt(unit.vel().angle());
}
}
2020-02-08 14:48:04 -05:00
if(omni){
2020-03-21 10:49:38 -04:00
unit.moveAt(movement);
2020-02-08 14:48:04 -05:00
}else{
2020-07-11 22:41:26 -04:00
unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len()));
if(!movement.isZero() && legs){
unit.vel.rotateTo(movement.angle(), unit.type().rotateSpeed * Time.delta);
}
2020-02-08 14:48:04 -05:00
}
unit.aim(unit.type().faceTarget ? Core.input.mouseWorld() : Tmp.v1.trns(unit.rotation, Core.input.mouseWorld().dst(unit)).add(unit.x, unit.y));
2020-07-09 13:13:57 -04:00
unit.controlWeapons(true, player.shooting && !boosted);
2020-02-07 11:46:10 -05:00
2020-07-09 13:13:57 -04:00
player.boosting = Core.input.keyDown(Binding.boost) && !movement.isZero();
player.mouseX = unit.aimX();
player.mouseY = unit.aimY();
2020-05-27 18:11:42 -04:00
//update payload input
2020-05-27 18:11:42 -04:00
if(unit instanceof Payloadc){
Payloadc pay = (Payloadc)unit;
if(Core.input.keyTap(Binding.pickupCargo) && pay.payloads().size < unit.type().payloadCapacity){
2020-07-17 19:00:39 -04:00
Unit target = Units.closest(player.team(), pay.x(), pay.y(), unit.type().hitsize * 2.5f, u -> u.isAI() && u.isGrounded() && u.mass() < unit.mass() && u.within(unit, u.hitSize + unit.hitSize * 1.2f));
2020-05-27 18:11:42 -04:00
if(target != null){
2020-07-09 20:58:49 -04:00
Call.pickupUnitPayload(player, target);
2020-05-27 18:11:42 -04:00
}else if(!pay.hasPayload()){
Building tile = world.buildWorld(pay.x(), pay.y());
2020-06-04 10:19:25 -04:00
2020-07-09 20:58:49 -04:00
if(tile != null && tile.team() == unit.team){
Call.pickupBlockPayload(player, tile);
2020-05-27 18:11:42 -04:00
}
}
}
if(Core.input.keyTap(Binding.dropCargo)){
2020-07-09 20:58:49 -04:00
Call.dropPayload(player, player.x, player.y);
2020-05-27 18:11:42 -04:00
pay.dropLastPayload();
}
}
2020-05-28 12:13:06 -04:00
//update commander inut
2020-05-28 12:13:06 -04:00
if(unit instanceof Commanderc){
if(Core.input.keyTap(Binding.command)){
Call.unitCommand(player);
2020-05-28 12:13:06 -04:00
}
}
2020-02-07 11:46:10 -05:00
}
2017-05-03 00:09:48 -04:00
}