Implemented shooting and states for ground units

This commit is contained in:
Anuken 2018-05-03 12:59:23 -04:00
parent 42b3b19a57
commit 2af750cfec
8 changed files with 127 additions and 50 deletions

View File

@ -89,7 +89,12 @@ public class Pathfinder {
}
path.search ++;
if(path.lastSearchTime + 1000/60*3 > TimeUtils.millis()){
path.frontier.clear();
}
path.lastSearchTime = TimeUtils.millis();
ObjectSet<Tile> set = world.indexer().getEnemy(team, BlockFlag.target);
for(Tile other : set){
@ -171,6 +176,7 @@ public class Pathfinder {
float[][] weights;
int[][] searches;
int search = 0;
long lastSearchTime;
Queue<Tile> frontier = new Queue<>();
PathData(){

View File

@ -1,25 +1,23 @@
package io.anuke.mindustry.entities.units;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.BlockFlag;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator;
import static io.anuke.mindustry.Vars.world;
public class FlyingUnitType extends UnitType {
protected static Vector2 vec = new Vector2();
protected static Translator vec = new Translator();
protected float boosterLength = 4.5f;
protected float retreatHealth = 10f;
protected float maxAim = 30f;
public FlyingUnitType(String name) {
@ -49,7 +47,10 @@ public class FlyingUnitType extends UnitType {
@Override
public void behavior(BaseUnit unit) {
if(unit.health <= health * retreatPercent &&
Geometry.findClosest(unit.x, unit.y, world.indexer().getAllied(unit.team, BlockFlag.repair)) != null){
unit.setState(retreat);
}
}
protected void circle(BaseUnit unit, float circleLength){
@ -128,7 +129,7 @@ public class FlyingUnitType extends UnitType {
}else{
attack(unit, 150f);
if (unit.timer.get(timerReload, 7) && Mathf.angNear(unit.angleTo(unit.target), unit.rotation, 13f)
if (unit.timer.get(timerReload, reload) && Mathf.angNear(unit.angleTo(unit.target), unit.rotation, 13f)
&& unit.distanceTo(unit.target) < unit.inventory.getAmmo().getRange()) {
AmmoType ammo = unit.inventory.getAmmo();
unit.inventory.useAmmo();

View File

@ -7,11 +7,15 @@ import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.game.TeamInfo.TeamData;
import io.anuke.mindustry.resource.AmmoType;
import io.anuke.mindustry.world.BlockFlag;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator;
@ -19,12 +23,9 @@ import static io.anuke.mindustry.Vars.state;
import static io.anuke.mindustry.Vars.world;
public abstract class GroundUnitType extends UnitType{
//only use for drawing!
protected Translator tr1 = new Translator();
//only use for updating!
protected Translator tr2 = new Translator();
protected static Translator vec = new Translator();
protected float jumpDistance = 4f;
protected float maxAim = 30f;
public GroundUnitType(String name) {
super(name);
@ -34,6 +35,11 @@ public abstract class GroundUnitType extends UnitType{
range = 40f;
}
@Override
public UnitState getStartState() {
return resupply;
}
@Override
public void update(BaseUnit unit) {
super.update(unit);
@ -56,8 +62,10 @@ public abstract class GroundUnitType extends UnitType{
}
for (int i : Mathf.signs) {
tr1.trns(unit.baseRotation, ft * i);
Draw.rect(name + "-leg", unit.x + tr1.x, unit.y + tr1.y, 12f * i, 12f - Mathf.clamp(ft * i, 0, 2), unit.baseRotation - 90);
Draw.rect(name + "-leg",
unit.x + Angles.trnsx(unit.baseRotation, ft * i),
unit.y + Angles.trnsy(unit.baseRotation, ft * i),
12f * i, 12f - Mathf.clamp(ft * i, 0, 2), unit.baseRotation - 90);
}
if(floor.liquid) {
@ -105,20 +113,100 @@ public abstract class GroundUnitType extends UnitType{
@Override
public void behavior(BaseUnit unit) {
if(unit.target instanceof TileEntity && unit.distanceTo(unit.target) < range) {
if(unit.timer.get(timerReload, reload)){
//shoot(unit, BulletType.shot, tr2.angle(), 4f);
if(unit.health <= health * retreatPercent){
unit.setState(retreat);
}
}
}else{
Tile targetTile = world.pathfinder().getTargetTile(unit.team, world.tileWorld(unit.x, unit.y));
tr2.trns(unit.baseRotation, speed);
protected void moveToCore(BaseUnit unit){
Tile tile = world.tileWorld(unit.x, unit.y);
Tile targetTile = world.pathfinder().getTargetTile(unit.team, tile);
if(tile == targetTile) return;
vec.trns(unit.baseRotation, speed);
unit.baseRotation = Mathf.slerpDelta(unit.baseRotation, unit.angleTo(targetTile), 0.05f);
unit.walkTime += Timers.delta();
unit.velocity.add(tr2);
unit.velocity.add(vec);
}
protected void moveAwayFromCore(BaseUnit unit){
Tile tile = world.tileWorld(unit.x, unit.y);
Tile targetTile = world.pathfinder().getTargetTile(state.teams.enemiesOf(unit.team).first(), tile);
if(tile == targetTile) return;
vec.trns(unit.baseRotation, speed);
unit.baseRotation = Mathf.slerpDelta(unit.baseRotation, unit.angleTo(targetTile), 0.05f);
unit.walkTime += Timers.delta();
unit.velocity.add(vec);
}
public final UnitState
resupply = new UnitState(){
public void entered(BaseUnit unit) {
unit.target = null;
}
public void update(BaseUnit unit) {
//TODO move toward resupply point?
if(unit.inventory.totalAmmo() + 10 >= unit.inventory.ammoCapacity()){
unit.state.set(unit, attack);
}
}
},
attack = new UnitState(){
public void entered(BaseUnit unit) {
unit.target = null;
}
public void update(BaseUnit unit) {
if(unit.target != null && (unit.target instanceof TileEntity &&
(((TileEntity)unit.target).tile.getTeam() == unit.team || !((TileEntity)unit.target).tile.breakable()))){
unit.target = null;
}
if(!unit.inventory.hasAmmo()) {
unit.state.set(unit, resupply);
}else if (unit.target == null){
if(unit.timer.get(timerTarget, 20)) {
Unit closest = Units.getClosestEnemy(unit.team, unit.x, unit.y,
unit.inventory.getAmmo().getRange(), other -> other.distanceTo(unit) < 60f);
if(closest != null){
unit.target = closest;
}else {
Tile target = Geometry.findClosest(unit.x, unit.y, world.indexer().getEnemy(unit.team, BlockFlag.resupplyPoint));
if (target != null) unit.target = target.entity;
}
}
}else{
moveToCore(unit);
if (unit.timer.get(timerReload, reload) && Mathf.angNear(unit.angleTo(unit.target), unit.rotation, 13f)
&& unit.distanceTo(unit.target) < unit.inventory.getAmmo().getRange()) {
AmmoType ammo = unit.inventory.getAmmo();
unit.inventory.useAmmo();
unit.rotate(unit.angleTo(unit.target));
shoot(unit, ammo, Angles.moveToward(unit.rotation, unit.angleTo(unit.target), maxAim), 4f);
}
}
}
},
retreat = new UnitState() {
public void entered(BaseUnit unit) {
unit.target = null;
}
public void update(BaseUnit unit) {
if(unit.health >= health){
unit.state.set(unit, attack);
}
moveAwayFromCore(unit);
}
};
}

View File

@ -42,6 +42,7 @@ public abstract class UnitType {
protected float drag = 0.1f;
protected float maxVelocity = 5f;
protected float reload = 40f;
protected float retreatPercent = 20f;
protected ObjectMap<Item, AmmoType> ammo = new ObjectMap<>();
public UnitType(String name){

View File

@ -1,11 +1,13 @@
package io.anuke.mindustry.entities.units.types;
import io.anuke.mindustry.content.AmmoTypes;
import io.anuke.mindustry.entities.units.GroundUnitType;
public class Brute extends GroundUnitType {
public Brute(String name) {
super(name);
setAmmo(AmmoTypes.basicIron);
}
}

View File

@ -6,15 +6,11 @@ import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.FlyingUnitType;
import io.anuke.mindustry.entities.units.UnitState;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.world.BlockFlag;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.world;
public class Cruiser extends FlyingUnitType {
@ -66,14 +62,6 @@ public class Cruiser extends FlyingUnitType {
}
}
@Override
public void behavior(BaseUnit unit) {
if(unit.health <= retreatHealth &&
Geometry.findClosest(unit.x, unit.y, world.indexer().getAllied(unit.team, BlockFlag.repair)) != null){
unit.setState(retreat);
}
}
@Override
public UnitState getStartState(){
return resupply;

View File

@ -1,10 +1,12 @@
package io.anuke.mindustry.entities.units.types;
import io.anuke.mindustry.content.AmmoTypes;
import io.anuke.mindustry.entities.units.GroundUnitType;
public class Scout extends GroundUnitType {
public Scout(){
super("scout");
setAmmo(AmmoTypes.basicIron);
}
}

View File

@ -7,15 +7,11 @@ import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.FlyingUnitType;
import io.anuke.mindustry.entities.units.UnitState;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.world.BlockFlag;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.world;
public class Vtol extends FlyingUnitType {
public Vtol(){
@ -23,6 +19,7 @@ public class Vtol extends FlyingUnitType {
setAmmo(AmmoTypes.basicIron);
speed = 0.3f;
maxVelocity = 2f;
reload = 7;
}
@Override
@ -69,14 +66,6 @@ public class Vtol extends FlyingUnitType {
}
}
@Override
public void behavior(BaseUnit unit) {
if(unit.health <= retreatHealth &&
Geometry.findClosest(unit.x, unit.y, world.indexer().getAllied(unit.team, BlockFlag.repair)) != null){
unit.setState(retreat);
}
}
@Override
public UnitState getStartState(){
return resupply;