From 1acb5fc56c5e121375cfdcff5c3ef84ba5ff8e6e Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 24 May 2020 10:11:28 -0400 Subject: [PATCH] Manual turret control --- core/src/mindustry/content/UnitTypes.java | 9 +++ .../entities/comp/BlockUnitComp.java | 32 +++++++++++ .../src/mindustry/entities/comp/TileComp.java | 6 +- .../mindustry/graphics/OverlayRenderer.java | 9 ++- core/src/mindustry/input/InputHandler.java | 6 ++ .../mindustry/world/blocks/ControlBlock.java | 13 +++++ .../defense/turrets/ArtilleryTurret.java | 6 +- .../world/blocks/defense/turrets/Turret.java | 56 ++++++++++++++----- 8 files changed, 115 insertions(+), 22 deletions(-) create mode 100644 core/src/mindustry/entities/comp/BlockUnitComp.java create mode 100644 core/src/mindustry/world/blocks/ControlBlock.java diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 708723f084..c192adcaf2 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -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; diff --git a/core/src/mindustry/entities/comp/BlockUnitComp.java b/core/src/mindustry/entities/comp/BlockUnitComp.java new file mode 100644 index 0000000000..7a66cc83ea --- /dev/null +++ b/core/src/mindustry/entities/comp/BlockUnitComp.java @@ -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); + } +} diff --git a/core/src/mindustry/entities/comp/TileComp.java b/core/src/mindustry/entities/comp/TileComp.java index 07528c029c..6c39d3d1bc 100644 --- a/core/src/mindustry/entities/comp/TileComp.java +++ b/core/src/mindustry/entities/comp/TileComp.java @@ -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; diff --git a/core/src/mindustry/graphics/OverlayRenderer.java b/core/src/mindustry/graphics/OverlayRenderer.java index 7f1916eca7..9f27bf6b5c 100644 --- a/core/src/mindustry/graphics/OverlayRenderer.java +++ b/core/src/mindustry/graphics/OverlayRenderer.java @@ -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(); diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index e8b5b39aba..bd5c15581d 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -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; } diff --git a/core/src/mindustry/world/blocks/ControlBlock.java b/core/src/mindustry/world/blocks/ControlBlock.java new file mode 100644 index 0000000000..acf4292337 --- /dev/null +++ b/core/src/mindustry/world/blocks/ControlBlock.java @@ -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(); + } +} diff --git a/core/src/mindustry/world/blocks/defense/turrets/ArtilleryTurret.java b/core/src/mindustry/world/blocks/defense/turrets/ArtilleryTurret.java index c064852392..71044999ce 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/ArtilleryTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/ArtilleryTurret.java @@ -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++){ diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index 3228977bd8..755a9b74c9 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -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 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(){