Time.delta cleanup / Basic mobile input
This commit is contained in:
@@ -186,7 +186,7 @@ public class DesktopInput extends InputHandler{
|
||||
if(!(scene.getKeyboardFocus() instanceof TextField) && !scene.hasDialog()){
|
||||
//move camera around
|
||||
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));
|
||||
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));
|
||||
|
||||
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;
|
||||
@@ -592,17 +592,18 @@ public class DesktopInput extends InputHandler{
|
||||
}else{
|
||||
unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len()));
|
||||
if(!movement.isZero() && legs){
|
||||
unit.vel().rotateTo(movement.angle(), unit.type().rotateSpeed * Time.delta());
|
||||
unit.vel.rotateTo(movement.angle(), unit.type().rotateSpeed * Time.delta);
|
||||
}
|
||||
}
|
||||
|
||||
unit.aim(unit.type().faceTarget ? Core.input.mouseWorld() : Tmp.v1.trns(unit.rotation(), Core.input.mouseWorld().dst(unit)).add(unit.x(), unit.y()));
|
||||
unit.aim(unit.type().faceTarget ? Core.input.mouseWorld() : Tmp.v1.trns(unit.rotation, Core.input.mouseWorld().dst(unit)).add(unit.x, unit.y));
|
||||
unit.controlWeapons(true, player.shooting && !boosted);
|
||||
|
||||
player.boosting = Core.input.keyDown(Binding.boost) && !movement.isZero();
|
||||
player.mouseX = unit.aimX();
|
||||
player.mouseY = unit.aimY();
|
||||
|
||||
//update payload input
|
||||
if(unit instanceof Payloadc){
|
||||
Payloadc pay = (Payloadc)unit;
|
||||
|
||||
@@ -611,7 +612,7 @@ public class DesktopInput extends InputHandler{
|
||||
if(target != null){
|
||||
Call.pickupUnitPayload(player, target);
|
||||
}else if(!pay.hasPayload()){
|
||||
Building tile = world.entWorld(pay.x(), pay.y());
|
||||
Building tile = world.buildWorld(pay.x(), pay.y());
|
||||
|
||||
if(tile != null && tile.team() == unit.team){
|
||||
Call.pickupBlockPayload(player, tile);
|
||||
@@ -625,6 +626,7 @@ public class DesktopInput extends InputHandler{
|
||||
}
|
||||
}
|
||||
|
||||
//update commander inut
|
||||
if(unit instanceof Commanderc){
|
||||
if(Core.input.keyTap(Binding.command)){
|
||||
Call.unitCommand(player);
|
||||
|
||||
@@ -322,7 +322,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
if(controlledType != null){
|
||||
Unit unit = Units.closest(player.team(), player.x, player.y, u -> !u.isPlayer() && u.type() == controlledType);
|
||||
if(unit == null && controlledType == UnitTypes.block){
|
||||
unit = world.entWorld(player.x, player.y) instanceof ControlBlock ? ((ControlBlock)world.entWorld(player.x, player.y)).unit() : null;
|
||||
unit = world.buildWorld(player.x, player.y) instanceof ControlBlock ? ((ControlBlock)world.buildWorld(player.x, player.y)).unit() : null;
|
||||
}
|
||||
|
||||
if(unit != null){
|
||||
@@ -798,7 +798,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
}
|
||||
|
||||
Building entAt(float x, float y){
|
||||
return world.ent(tileX(x), tileY(y));
|
||||
return world.build(tileX(x), tileY(y));
|
||||
}
|
||||
|
||||
/** Returns the tile at the specified MOUSE coordinates. */
|
||||
@@ -856,7 +856,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
}
|
||||
}
|
||||
|
||||
Building tile = world.entWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
||||
Building tile = world.buildWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
||||
if(tile instanceof ControlBlock && tile.team() == player.team()){
|
||||
return ((ControlBlock)tile).unit();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mindustry.input;
|
||||
|
||||
import arc.*;
|
||||
import arc.struct.*;
|
||||
import arc.func.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.input.GestureDetector.*;
|
||||
@@ -11,15 +10,17 @@ import arc.math.geom.*;
|
||||
import arc.scene.*;
|
||||
import arc.scene.ui.ImageButton.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.game.EventType.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
@@ -33,7 +34,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
private final float edgePan = Scl.scl(60f);
|
||||
|
||||
//gesture data
|
||||
private Vec2 vector = new Vec2();
|
||||
private Vec2 vector = new Vec2(), movement = new Vec2(), targetPos = new Vec2();
|
||||
private float lastZoom = -1;
|
||||
|
||||
/** Position where the player started dragging a line. */
|
||||
@@ -62,7 +63,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
/** Down tracking for panning.*/
|
||||
private boolean down = false;
|
||||
|
||||
private Teamc target;
|
||||
private Teamc target, moveTarget;
|
||||
|
||||
//region utility methods
|
||||
|
||||
@@ -74,16 +75,15 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
player.miner().mineTile(null);
|
||||
target = unit;
|
||||
}else{
|
||||
Building tile = world.entWorld(x, y);
|
||||
Building tile = world.buildWorld(x, y);
|
||||
|
||||
if(tile != null && player.team().isEnemy(tile.team())){
|
||||
player.miner().mineTile(null);
|
||||
target = tile;
|
||||
//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;
|
||||
// }
|
||||
}else if(tile != null && player.unit().type().canHeal && tile.team == player.team() && tile.damaged()){
|
||||
player.miner().mineTile(null);
|
||||
target = tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,27 +505,40 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
@Override
|
||||
public boolean longPress(float x, float y){
|
||||
if(state.isMenu() || mode == none || player.dead()) return false;
|
||||
if(state.isMenu()|| player.dead()) return false;
|
||||
|
||||
//get tile on cursor
|
||||
Tile cursor = tileAt(x, y);
|
||||
|
||||
//ignore off-screen taps
|
||||
if(cursor == null || Core.scene.hasMouse(x, y) || schematicMode) return false;
|
||||
if(Core.scene.hasMouse(x, y) || schematicMode) return false;
|
||||
|
||||
//remove request if it's there
|
||||
//long pressing enables line mode otherwise
|
||||
lineStartX = cursor.x;
|
||||
lineStartY = cursor.y;
|
||||
lastLineX = cursor.x;
|
||||
lastLineY = cursor.y;
|
||||
lineMode = true;
|
||||
//handle long tap when player isn't building
|
||||
if(mode == none){
|
||||
|
||||
if(mode == breaking){
|
||||
Fx.tapBlock.at(cursor.worldx(), cursor.worldy(), 1f);
|
||||
}else if(block != null){
|
||||
updateLine(lineStartX, lineStartY, cursor.x, cursor.y);
|
||||
Fx.tapBlock.at(cursor.worldx() + block.offset(), cursor.worldy() + block.offset(), block.size);
|
||||
//control a unit/block
|
||||
Unit on = selectedUnit();
|
||||
if(on != null){
|
||||
Call.unitControl(player, on);
|
||||
}
|
||||
}else{
|
||||
|
||||
//ignore off-screen taps
|
||||
if(cursor == null) return false;
|
||||
|
||||
//remove request if it's there
|
||||
//long pressing enables line mode otherwise
|
||||
lineStartX = cursor.x;
|
||||
lineStartY = cursor.y;
|
||||
lastLineX = cursor.x;
|
||||
lastLineY = cursor.y;
|
||||
lineMode = true;
|
||||
|
||||
if(mode == breaking){
|
||||
Fx.tapBlock.at(cursor.worldx(), cursor.worldy(), 1f);
|
||||
}else if(block != null){
|
||||
updateLine(lineStartX, lineStartY, cursor.x, cursor.y);
|
||||
Fx.tapBlock.at(cursor.worldx() + block.offset(), cursor.worldy() + block.offset(), block.size);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -584,7 +597,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
if(!Core.settings.getBool("keyboard")){
|
||||
//move camera around
|
||||
float camSpeed = 6f;
|
||||
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));
|
||||
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));
|
||||
}
|
||||
|
||||
if(Core.settings.getBool("keyboard")){
|
||||
@@ -597,6 +610,10 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
}
|
||||
}
|
||||
|
||||
if(!player.dead() && !state.isPaused()){
|
||||
updateMovement(player.unit());
|
||||
}
|
||||
|
||||
//reset state when not placing
|
||||
if(mode == none){
|
||||
lineMode = false;
|
||||
@@ -755,5 +772,137 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
return true;
|
||||
}
|
||||
|
||||
//endregion
|
||||
//region movement
|
||||
|
||||
protected void updateMovement(Unit unit){
|
||||
Rect rect = Tmp.r3;
|
||||
|
||||
UnitType type = unit.type();
|
||||
boolean flying = type.flying;
|
||||
boolean omni = !(unit instanceof WaterMovec);
|
||||
boolean legs = unit.isGrounded();
|
||||
boolean allowHealing = type.canHeal;
|
||||
boolean validHealTarget = allowHealing && target instanceof Building && ((Building)target).isValid() && target.team() == unit.team &&
|
||||
((Building)target).damaged() && target.within(unit, type.range);
|
||||
boolean boosted = (unit instanceof Mechc && unit.isFlying());
|
||||
|
||||
//reset target if:
|
||||
// - in the editor, or...
|
||||
// - it's both an invalid standard target and an invalid heal target
|
||||
if((Units.invalidateTarget(target, unit, type.range) && !validHealTarget) || state.isEditor()){
|
||||
target = null;
|
||||
}
|
||||
|
||||
targetPos.set(Core.camera.position);
|
||||
float attractDst = 15f;
|
||||
float strafePenalty = legs ? 1f : Mathf.lerp(1f, type.strafePenalty, Angles.angleDist(unit.vel.angle(), unit.rotation) / 180f);
|
||||
float speed = type.speed * Mathf.lerp(1f, type.canBoost ? type.boostMultiplier : 1f, unit.elevation()) * strafePenalty;
|
||||
float range = unit.hasWeapons() ? unit.range() : 0f;
|
||||
float bulletSpeed = unit.hasWeapons() ? type.weapons.first().bullet.speed : 0f;
|
||||
float mouseAngle = unit.angleTo(unit.aimX(), unit.aimY());
|
||||
boolean aimCursor = omni && player.shooting && type.hasWeapons() && type.faceTarget && !boosted && type.rotateShooting;
|
||||
|
||||
if(aimCursor){
|
||||
unit.lookAt(mouseAngle);
|
||||
}else{
|
||||
if(unit.moving()){
|
||||
unit.lookAt(unit.vel.angle());
|
||||
}
|
||||
}
|
||||
|
||||
if(moveTarget != null){
|
||||
targetPos.set(moveTarget);
|
||||
attractDst = 0f;
|
||||
|
||||
if(unit.within(moveTarget, 2f * Time.delta)){
|
||||
handleTapTarget(moveTarget);
|
||||
moveTarget = null;
|
||||
}
|
||||
}
|
||||
|
||||
movement.set(targetPos).sub(player).limit(speed);
|
||||
movement.setAngle(Mathf.slerp(movement.angle(), unit.vel.angle(), 0.05f));
|
||||
|
||||
//pathfind for ground units
|
||||
if(!flying && !type.canBoost && !(unit instanceof WaterMovec)){
|
||||
Tile on = unit.tileOn();
|
||||
if(on != null && !on.solid()){
|
||||
Tile to = pathfinder.getTargetTile(unit.tileOn(), unit.team, targetPos);
|
||||
if(to != null){
|
||||
movement.set(to).sub(unit).setLength(speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(player.within(targetPos, attractDst)){
|
||||
movement.setZero();
|
||||
}
|
||||
|
||||
float expansion = 3f;
|
||||
|
||||
unit.hitbox(rect);
|
||||
rect.x -= expansion;
|
||||
rect.y -= expansion;
|
||||
rect.width += expansion * 2f;
|
||||
rect.height += expansion * 2f;
|
||||
|
||||
player.boosting = collisions.overlapsTile(rect) || !unit.within(targetPos, 85f);
|
||||
|
||||
if(omni){
|
||||
unit.moveAt(movement);
|
||||
}else{
|
||||
unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len()));
|
||||
if(!movement.isZero() && legs){
|
||||
unit.vel.rotateTo(movement.angle(), type.rotateSpeed * Time.delta);
|
||||
}
|
||||
}
|
||||
|
||||
if(flying){
|
||||
//hovering effect
|
||||
unit.x += Mathf.sin(Time.time(), 25f, 0.08f);
|
||||
unit.y += Mathf.cos(Time.time(), 25f, 0.08f);
|
||||
}
|
||||
|
||||
//update shooting if not building + not mining
|
||||
if(!player.builder().isBuilding() && player.miner().mineTile() == null){
|
||||
|
||||
//autofire
|
||||
if(target == null){
|
||||
player.shooting = false;
|
||||
if(Core.settings.getBool("autotarget")){
|
||||
target = Units.closestTarget(unit.team, unit.x, unit.y, range, u -> u.team != Team.derelict, u -> u.team != Team.derelict);
|
||||
|
||||
if(allowHealing && target == null){
|
||||
target = Geometry.findClosest(unit.x, unit.y, indexer.getDamaged(Team.sharded));
|
||||
if(target != null && !unit.within(target, range)){
|
||||
target = null;
|
||||
}
|
||||
}
|
||||
|
||||
if(target != null && player.isMiner()){
|
||||
player.miner().mineTile(null);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
Vec2 intercept = Predict.intercept(unit, target, bulletSpeed);
|
||||
|
||||
player.mouseX = intercept.x;
|
||||
player.mouseY = intercept.y;
|
||||
player.shooting = true;
|
||||
|
||||
unit.aim(player.mouseX, player.mouseY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unit.controlWeapons(player.shooting && !boosted);
|
||||
}
|
||||
|
||||
|
||||
protected void handleTapTarget(Teamc target){
|
||||
|
||||
}
|
||||
|
||||
//endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user