Implemented drone sprite, basic AI
This commit is contained in:
@@ -154,6 +154,7 @@ public abstract class Unit extends SyncEntity implements SerializableEntity {
|
||||
}
|
||||
|
||||
public void drawUnder(){}
|
||||
public void drawOver(){}
|
||||
|
||||
public abstract boolean acceptsAmmo(Item item);
|
||||
public abstract void addAmmo(Item item);
|
||||
|
||||
@@ -101,6 +101,10 @@ public class BaseUnit extends Unit{
|
||||
type.drawUnder(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawOver(){
|
||||
type.drawOver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float drawSize(){
|
||||
|
||||
@@ -33,7 +33,6 @@ public class FlyingUnitType extends UnitType {
|
||||
super.update(unit);
|
||||
|
||||
unit.rotation = unit.velocity.angle();
|
||||
unit.state.update(unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -13,4 +13,8 @@ public class StateMachine {
|
||||
this.state = next;
|
||||
if(next != null) next.entered(unit);
|
||||
}
|
||||
|
||||
public boolean is(UnitState state){
|
||||
return this.state == state;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import io.anuke.mindustry.content.fx.ExplosionFx;
|
||||
import io.anuke.mindustry.entities.Bullet;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.entities.Unit;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.NetEvents;
|
||||
@@ -42,7 +43,7 @@ public abstract class UnitType {
|
||||
protected float drag = 0.1f;
|
||||
protected float maxVelocity = 5f;
|
||||
protected float reload = 40f;
|
||||
protected float retreatPercent = 20f;
|
||||
protected float retreatPercent = 0.2f;
|
||||
protected ObjectMap<Item, AmmoType> ammo = new ObjectMap<>();
|
||||
|
||||
public UnitType(String name){
|
||||
@@ -59,12 +60,14 @@ public abstract class UnitType {
|
||||
|
||||
public abstract void draw(BaseUnit unit);
|
||||
|
||||
public void drawUnder(BaseUnit unit){}
|
||||
|
||||
public void drawOver(BaseUnit unit){}
|
||||
|
||||
public UnitState getStartState(){
|
||||
return null;
|
||||
}
|
||||
|
||||
public void drawUnder(BaseUnit unit){}
|
||||
|
||||
public boolean isFlying(){
|
||||
return isFlying;
|
||||
}
|
||||
@@ -83,6 +86,7 @@ public abstract class UnitType {
|
||||
|
||||
updateTargeting(unit);
|
||||
|
||||
unit.state.update(unit);
|
||||
unit.updateVelocityStatus(drag, maxVelocity);
|
||||
|
||||
if(unit.target != null) behavior(unit);
|
||||
@@ -95,7 +99,8 @@ public abstract class UnitType {
|
||||
public abstract void behavior(BaseUnit unit);
|
||||
|
||||
public void updateTargeting(BaseUnit unit){
|
||||
if(unit.target == null || (unit.target instanceof Unit && (((Unit)unit.target).isDead() || ((Unit)unit.target).team == unit.team))){
|
||||
if(unit.target == null || (unit.target instanceof Unit && (((Unit)unit.target).isDead() || ((Unit)unit.target).team == unit.team))
|
||||
|| (unit.target instanceof TileEntity && ((TileEntity) unit.target).tile.entity == null)){
|
||||
unit.target = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,123 @@
|
||||
package io.anuke.mindustry.entities.units.types;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.entities.Units;
|
||||
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.world.BlockFlag;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Shapes;
|
||||
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 Drone extends FlyingUnitType {
|
||||
protected float healSpeed = 0.1f;
|
||||
protected float discoverRange = 120f;
|
||||
|
||||
public Drone(String name) {
|
||||
super(name);
|
||||
public Drone() {
|
||||
super("drone");
|
||||
speed = 0.2f;
|
||||
maxVelocity = 0.8f;
|
||||
range = 50f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(BaseUnit unit) {
|
||||
float rot = unit.rotation;
|
||||
super.update(unit);
|
||||
unit.rotation = rot;
|
||||
|
||||
if(unit.target != null && unit.state.is(repair)){
|
||||
unit.rotation = Mathf.slerpDelta(rot, unit.angleTo(unit.target), 0.3f);
|
||||
}else{
|
||||
unit.rotation = Mathf.slerpDelta(rot, unit.velocity.angle(), 0.3f);
|
||||
}
|
||||
|
||||
unit.x += Mathf.sin(Timers.time() + unit.id * 999, 25f, 0.07f);
|
||||
unit.y += Mathf.cos(Timers.time() + unit.id * 999, 25f, 0.07f);
|
||||
|
||||
if(unit.velocity.len() <= 0.2f && !(unit.state.is(repair) && unit.target != null)){
|
||||
unit.rotation += Mathf.sin(Timers.time() + unit.id * 99, 10f, 5f);
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnitState getStartState() {
|
||||
return repair;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawOver(BaseUnit unit) {
|
||||
if(unit.target instanceof TileEntity && unit.state.is(repair)){
|
||||
float len = 5f;
|
||||
Draw.color(Color.BLACK, Color.WHITE, 0.95f + Mathf.absin(Timers.time(), 0.8f, 0.05f));
|
||||
Shapes.laser("beam", "beam-end",
|
||||
unit.x + Angles.trnsx(unit.rotation, len),
|
||||
unit.y + Angles.trnsy(unit.rotation, len),
|
||||
unit.target.x, unit.target.y);
|
||||
Draw.color();
|
||||
}
|
||||
}
|
||||
|
||||
public final UnitState
|
||||
|
||||
repair = new UnitState(){
|
||||
public void entered(BaseUnit unit) {
|
||||
unit.target = null;
|
||||
}
|
||||
|
||||
public void update(BaseUnit unit) {
|
||||
if(unit.target != null && (((TileEntity)unit.target).health >= ((TileEntity)unit.target).tile.block().health
|
||||
|| unit.target.distanceTo(unit) > discoverRange)){
|
||||
unit.target = null;
|
||||
}
|
||||
|
||||
if (unit.target == null) {
|
||||
if (unit.timer.get(timerTarget, 20)) {
|
||||
unit.target = Units.findAllyTile(unit.team, unit.x, unit.y, discoverRange,
|
||||
tile -> tile.entity != null && tile.entity.health + 0.0001f < tile.block().health);
|
||||
}
|
||||
}else if(unit.target.distanceTo(unit) > range){
|
||||
circle(unit, range);
|
||||
}else{
|
||||
TileEntity entity = (TileEntity) unit.target;
|
||||
entity.health += healSpeed * Timers.delta();
|
||||
entity.health = Mathf.clamp(entity.health, 0, entity.tile.block().health);
|
||||
}
|
||||
}
|
||||
},
|
||||
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);
|
||||
}else if(!unit.targetHasFlag(BlockFlag.repair)){
|
||||
if(unit.timer.get(timerTarget, 20)) {
|
||||
Tile target = Geometry.findClosest(unit.x, unit.y, world.indexer().getAllied(unit.team, BlockFlag.repair));
|
||||
if (target != null) unit.target = target.entity;
|
||||
}
|
||||
}else{
|
||||
circle(unit, 40f);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user