Manual turret control

This commit is contained in:
Anuken 2020-05-24 10:11:28 -04:00
parent 503b947fb7
commit 1acb5fc56c
8 changed files with 115 additions and 22 deletions

View file

@ -33,8 +33,17 @@ public class UnitTypes implements ContentList{
//water
public static @EntityDef({Unitc.class, WaterMovec.class, Commanderc.class}) UnitType vanguard;
//special block unit type
public static @EntityDef({Unitc.class, BlockUnitc.class}) UnitType block;
@Override
public void load(){
block = new UnitType("block"){{
speed = 0f;
hitsize = 0f;
health = 1;
rotateSpeed = 360f;
}};
dagger = new UnitType("dagger"){{
speed = 0.5f;

View file

@ -0,0 +1,32 @@
package mindustry.entities.comp;
import arc.util.ArcAnnotate.*;
import mindustry.annotations.Annotations.*;
import mindustry.gen.*;
import static mindustry.Vars.tilesize;
@Component
abstract class BlockUnitComp implements Unitc{
@ReadOnly @NonNull Tilec tile;
public void tile(Tilec tile){
this.tile = tile;
//sets up block stats
maxHealth(tile.block().health);
health(tile.health());
hitSize(tile.block().size * tilesize);
set(tile);
}
@Replace
public void kill(){
tile.kill();
}
@Replace
public void damage(float v, boolean b){
tile.damage(v, b);
}
}

View file

@ -60,7 +60,7 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree
private transient float timeScale = 1f, timeScaleDuration;
private transient @Nullable mindustry.audio.SoundLoop sound;
private transient @Nullable SoundLoop sound;
private transient boolean sleeping;
private transient float sleepTime;
@ -84,6 +84,8 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree
add();
}
created();
return this;
}
@ -296,6 +298,8 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree
//endregion
//region handler methods
public void created(){}
public boolean shouldConsume(){
return true;

View file

@ -76,7 +76,14 @@ public class OverlayRenderer{
if(select != null && select.isAI()){
Draw.mixcol(Pal.accent, 1f);
Draw.alpha(unitFade);
Draw.rect(select.type().icon(Cicon.full), select.x(), select.y(), select.rotation() - 90);
if(select instanceof BlockUnitc){
//special selection for block "units"
Fill.square(select.x(), select.y(), ((BlockUnitc)select).tile().block().size * tilesize/2f);
}else{
Draw.rect(select.type().icon(Cicon.full), select.x(), select.y(), select.rotation() - 90);
}
Lines.stroke(unitFade);
Lines.square(select.x(), select.y(), select.hitSize() * 1.5f, Time.time() * 2f);
Draw.reset();

View file

@ -748,6 +748,12 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
return unit;
}
}
Tilec tile = world.entWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
if(tile instanceof ControlBlock){
return ((ControlBlock)tile).unit();
}
return null;
}

View file

@ -0,0 +1,13 @@
package mindustry.world.blocks;
import mindustry.gen.*;
/** Any block that has a proxy unit that can be controlled by a player. */
public interface ControlBlock{
Unitc unit();
/** @return whether this block is being controlled by a player. */
default boolean isControlled(){
return unit().isPlayer();
}
}

View file

@ -1,8 +1,6 @@
package mindustry.world.blocks.defense.turrets;
import arc.math.*;
import arc.math.geom.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
import static mindustry.Vars.tilesize;
@ -28,9 +26,7 @@ public class ArtilleryTurret extends ItemTurret{
tr.trns(rotation, size * tilesize / 2);
Vec2 predict = Predict.intercept(tile, target, type.speed);
float dst = dst(predict.x, predict.y);
float dst = dst(targetPos.x, targetPos.y);
float maxTraveled = type.lifetime * type.speed;
for(int i = 0; i < shots; i++){

View file

@ -9,6 +9,7 @@ import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import arc.util.ArcAnnotate.*;
import arc.util.io.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
@ -17,6 +18,7 @@ import mindustry.entities.bullet.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.meta.*;
import static mindustry.Vars.tilesize;
@ -108,12 +110,24 @@ public abstract class Turret extends Block{
public abstract BulletType type();
}
public class TurretEntity extends TileEntity{
public class TurretEntity extends TileEntity implements ControlBlock{
public Array<AmmoEntry> ammo = new Array<>();
public int totalAmmo;
public float reload, rotation = 90, recoil, heat;
public int shotCounter;
public Posc target;
public @Nullable Posc target;
public Vec2 targetPos = new Vec2();
public @NonNull BlockUnitc unit = Nulls.blockUnit;
public void created(){
unit = (BlockUnitc)UnitTypes.block.create(team);
unit.tile(this);
}
@Override
public Unitc unit(){
return unit;
}
@Override
public void draw(){
@ -138,6 +152,10 @@ public abstract class Turret extends Block{
recoil = Mathf.lerpDelta(recoil, 0f, restitution);
heat = Mathf.lerpDelta(heat, 0f, cooldown);
unit.health(health);
unit.rotation(rotation);
unit.team(team);
if(hasAmmo()){
if(timer(timerTarget, targetInterval)){
@ -145,27 +163,35 @@ public abstract class Turret extends Block{
}
if(validateTarget()){
boolean canShoot = true;
BulletType type = peekAmmo();
float speed = type.speed;
if(speed < 0.1f) speed = 9999999f;
//player behavior
if(isControlled()){
targetPos.set(unit.aimX(), unit.aimY());
canShoot = unit.isShooting();
}else{ //default AI behavior
BulletType type = peekAmmo();
float speed = type.speed;
//slow bullets never intersect
if(speed < 0.1f) speed = 9999999f;
Vec2 result = Predict.intercept(this, target, speed);
if(result.isZero()){
result.set(target.getX(), target.getY());
targetPos.set(Predict.intercept(this, target, speed));
if(targetPos.isZero()){
targetPos.set(target);
}
if(Float.isNaN(rotation)){
rotation = 0;
}
}
float targetRot = result.sub(x, y).angle();
if(Float.isNaN(rotation)){
rotation = 0;
}
float targetRot = angleTo(targetPos);
if(shouldTurn()){
turnToTarget(targetRot);
}
if(Angles.angleDist(rotation, targetRot) < shootCone){
if(Angles.angleDist(rotation, targetRot) < shootCone && canShoot){
updateShooting();
}
}
@ -179,7 +205,7 @@ public abstract class Turret extends Block{
}
protected boolean validateTarget(){
return !Units.invalidateTarget(target, team, x, y);
return !Units.invalidateTarget(target, team, x, y) || isControlled();
}
protected void findTarget(){