Unit weapon rework, titan and bomber enemies added, various fixes

This commit is contained in:
Anuken
2018-06-26 22:48:18 -04:00
parent 03277c69af
commit c89123b18a
48 changed files with 1154 additions and 879 deletions
@@ -16,6 +16,7 @@ import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.impl.SolidEntity;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Physics;
import io.anuke.ucore.util.Translator;
@@ -108,8 +109,10 @@ public class Damage {
}
/**Damages all entities and blocks in a radius that are enemies of the team.*/
public static void damageUnits(Team team, float x, float y, float size, float damage, Consumer<Unit> acceptor) {
public static void damageUnits(Team team, float x, float y, float size, float damage, Predicate<Unit> predicate, Consumer<Unit> acceptor) {
Consumer<Unit> cons = entity -> {
if(!predicate.test(entity)) return;
entity.getHitbox(hitrect);
if (!hitrect.overlaps(rect)) {
return;
@@ -134,13 +137,14 @@ public class Damage {
/**Damages all entities and blocks in a radius that are enemies of the team.*/
public static void damage(Team team, float x, float y, float radius, float damage){
Consumer<Unit> cons = entity -> {
if(entity.distanceTo(x, y) > radius){
if(entity.team == team || entity.distanceTo(x, y) > radius){
return;
}
float amount = calculateDamage(x, y, entity.x, entity.y, radius, damage);
entity.damage(amount);
//TODO better velocity displacement
entity.getVelocity().add(tr.set(entity.x - x, entity.y - y).setLength(damage*2f));
float dst = tr.set(entity.x - x, entity.y - y).len();
entity.getVelocity().add(tr.setLength((1f-dst/radius) * 2f));
};
rect.setSize(radius *2).setCenter(x, y);
@@ -11,20 +11,14 @@ import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.effect.ItemDrop;
import io.anuke.mindustry.entities.effect.ScorchDecal;
import io.anuke.mindustry.entities.traits.BuilderTrait;
import io.anuke.mindustry.entities.traits.CarriableTrait;
import io.anuke.mindustry.entities.traits.CarryTrait;
import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.gen.CallEntity;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Trail;
import io.anuke.mindustry.net.In;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.type.Mech;
import io.anuke.mindustry.type.Upgrade;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
@@ -34,10 +28,7 @@ import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.ThreadQueue;
import io.anuke.ucore.util.Timer;
import io.anuke.ucore.util.*;
import java.io.DataInput;
import java.io.DataOutput;
@@ -45,11 +36,10 @@ import java.io.IOException;
import static io.anuke.mindustry.Vars.*;
public class Player extends Unit implements BuilderTrait, CarryTrait {
public static int typeID = -1;
public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTrait {
private static final int timerShootLeft = 0;
private static final int timerShootRight = 1;
public static final int timerShootLeft = 0;
public static final int timerShootRight = 1;
public static final int timerSync = 2;
//region instance variables, constructor
@@ -90,6 +80,21 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
//region unit and event overrides, utility methods
@Override
public Timer getTimer() {
return timer;
}
@Override
public int getShootTimer(boolean left) {
return left ? timerShootLeft : timerShootRight;
}
@Override
public Weapon getWeapon() {
return mech.weapon;
}
@Override
public float getMinePower() {
return mech.mineSpeed;
@@ -123,11 +128,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
}
}
@Override
public int getTypeID() {
return typeID;
}
@Override
public CarriableTrait getCarry() {
return carrying;
@@ -538,8 +538,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
protected void updateShooting(){
if(isShooting()){
mech.weapon.update(this, true, pointerX, pointerY);
mech.weapon.update(this, false, pointerX, pointerY);
mech.weapon.update(this, pointerX, pointerY);
}
}
@@ -31,7 +31,7 @@ import java.io.IOException;
import static io.anuke.mindustry.Vars.state;
import static io.anuke.mindustry.Vars.world;
public abstract class Unit extends DestructibleEntity implements SaveTrait, TargetTrait, SyncTrait, DrawTrait, TeamTrait, CarriableTrait {
public abstract class Unit extends DestructibleEntity implements SaveTrait, TargetTrait, SyncTrait, DrawTrait, TeamTrait, CarriableTrait, InventoryTrait {
/**total duration of hit flash effect*/
public static final float hitDuration = 9f;
/**Percision divisor of velocity, used when writing. For example a value of '2' would mean the percision is 1/2 = 0.5-size chunks.*/
@@ -53,6 +53,11 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
protected float hitTime;
protected float drownTime;
@Override
public UnitInventory getInventory() {
return inventory;
}
@Override
public float getRotation() {
return rotation;
@@ -191,7 +196,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
public void avoidOthers(float avoidRange){
EntityPhysics.getNearby(getGroup(), x, y, avoidRange*2f, t -> {
if(t == this || (t instanceof Unit && ((Unit) t).isDead())) return;
if(t == this || (t instanceof Unit && (((Unit) t).isDead() || (((Unit) t).isFlying() != isFlying())))) return;
float dst = distanceTo(t);
if(dst > avoidRange) return;
velocity.add(moveVector.set(x, y).sub(t.getX(), t.getY()).setLength(1f * (1f - (dst / avoidRange))));
@@ -0,0 +1,16 @@
package io.anuke.mindustry.entities.bullet;
public class BombBulletType extends BasicBulletType {
public BombBulletType(float damage, float radius, String sprite) {
super(0.7f, 0, sprite);
splashDamageRadius = radius;
splashDamage = damage;
collidesTiles = false;
collides = false;
bulletShrink = 0.7f;
lifetime = 30f;
drag = 0.05f;
keepVelocity = false;
}
}
@@ -27,8 +27,6 @@ import static io.anuke.mindustry.Vars.bulletGroup;
import static io.anuke.mindustry.Vars.world;
public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncTrait{
public static int typeID = -1;
private static Vector2 vector = new Vector2();
private Team team;
@@ -56,7 +54,9 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
bullet.data = data;
bullet.velocity.set(0, type.speed).setAngle(angle).scl(velocityScl);
bullet.velocity.add(owner instanceof VelocityTrait ? ((VelocityTrait)owner).getVelocity() : Vector2.Zero);
if(type.keepVelocity){
bullet.velocity.add(owner instanceof VelocityTrait ? ((VelocityTrait)owner).getVelocity() : Vector2.Zero);
}
bullet.hitbox.setSize(type.hitsize);
bullet.team = team;
@@ -119,11 +119,6 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
return super.getDamage();
}
@Override
public int getTypeID() {
return typeID;
}
@Override
public boolean isSyncing(){
return type.syncable;
@@ -29,6 +29,8 @@ public abstract class BulletType extends BaseBulletType<Bullet> implements Conte
public boolean collidesTiles = true;
/**Whether this bullet types collides with anything at all.*/
public boolean collides = true;
/**Whether velocity is inherited from the shooter.*/
public boolean keepVelocity = true;
public BulletType(float speed, float damage){
this.id = lastid ++;
@@ -34,8 +34,6 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
private static final IntMap<Fire> map = new IntMap<>();
private static final float baseLifetime = 1000f;
public static int typeID = -1;
private int loadedPosition = -1;
private Tile tile;
private Block block;
@@ -71,11 +69,6 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
/**Deserialization use only!*/
public Fire(){}
@Override
public int getTypeID() {
return typeID;
}
@Override
public float lifetime() {
return lifetime;
@@ -137,11 +130,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
if(damage){
entity.damage(0.4f);
}
Damage.damageUnits(null, tile.worldx(), tile.worldy(), tilesize, 3f, unit -> {
if(!unit.isFlying()) {
unit.applyEffect(StatusEffects.burning, 0.8f);
}
});
Damage.damageUnits(null, tile.worldx(), tile.worldy(), tilesize, 3f, unit -> !unit.isFlying(), unit -> unit.applyEffect(StatusEffects.burning, 0.8f));
}
}
@@ -37,8 +37,6 @@ import java.io.IOException;
import static io.anuke.mindustry.Vars.*;
public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawTrait, VelocityTrait, TimeTrait, TargetTrait, Poolable {
public static int typeID = -1;
private static final float sinkLifetime = 80f;
private Interpolator interpolator = new Interpolator();
@@ -98,11 +96,6 @@ public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawT
return Team.none;
}
@Override
public int getTypeID() {
return typeID;
}
@Override
public float lifetime() {
return 60*60;
@@ -49,8 +49,6 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
private static final Rectangle rect2 = new Rectangle();
private static int seeds;
public static int typeID = -1;
private int loadedPosition = -1;
private float updateTime;
@@ -269,11 +267,6 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
reset();
}
@Override
public int getTypeID() {
return typeID;
}
@Override
public void write(DataOutput data) throws IOException {
data.writeFloat(x);
@@ -0,0 +1,7 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.mindustry.entities.UnitInventory;
public interface InventoryTrait {
UnitInventory getInventory();
}
@@ -0,0 +1,12 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.mindustry.type.Weapon;
import io.anuke.ucore.entities.trait.VelocityTrait;
import io.anuke.ucore.util.Timer;
public interface ShooterTrait extends VelocityTrait, TeamTrait, InventoryTrait{
Timer getTimer();
int getShootTimer(boolean left);
Weapon getWeapon();
}
@@ -1,18 +1,24 @@
package io.anuke.mindustry.entities.traits;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectIntMap;
import io.anuke.ucore.function.Supplier;
public interface TypeTrait {
int[] lastRegisteredID = {0};
Array<Supplier<? extends TypeTrait>> registeredTypes = new Array<>();
ObjectIntMap<Class<? extends TypeTrait>> typeToID = new ObjectIntMap<>();
/**Register and return a type ID. The supplier should return a fresh instace of that type.*/
static int registerType(Supplier<? extends TypeTrait> supplier){
static <T extends TypeTrait> void registerType(Class<T> type, Supplier<T> supplier){
if(typeToID.get(type, -1) != -1){
throw new RuntimeException("Type is already registered: '" + type + "'!");
}
registeredTypes.add(supplier);
int result = lastRegisteredID[0];
typeToID.put(type, result);
lastRegisteredID[0] ++;
return result;
}
/**Registers a syncable type by ID.*/
@@ -23,6 +29,11 @@ public interface TypeTrait {
return registeredTypes.get(id);
}
/**Returns the type ID of this entity used for intstantiation. Should be < BYTE_MAX.*/
int getTypeID();
/**Returns the type ID of this entity used for intstantiation. Should be < BYTE_MAX.
* Do not override!*/
default int getTypeID(){
int id = typeToID.get(getClass(), -1);
if(id == -1) throw new RuntimeException("Class of type '" + getClass() + "' is not registered! Did you forget to register it in ContentLoader#registerTypes()?");
return id;
}
}
@@ -1,7 +1,6 @@
package io.anuke.mindustry.entities.units;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectSet;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
@@ -10,24 +9,22 @@ import io.anuke.mindustry.content.fx.ExplosionFx;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.bullet.Bullet;
import io.anuke.mindustry.entities.effect.ScorchDecal;
import io.anuke.mindustry.entities.traits.ShooterTrait;
import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.game.TeamInfo.TeamData;
import io.anuke.mindustry.gen.CallEntity;
import io.anuke.mindustry.net.In;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.units.UnitFactory.UnitFactoryEntity;
import io.anuke.mindustry.world.meta.BlockFlag;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
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.Timer;
@@ -38,13 +35,13 @@ import java.io.IOException;
import static io.anuke.mindustry.Vars.*;
public abstract class BaseUnit extends Unit{
private static int timerIndex = 0;
public abstract class BaseUnit extends Unit implements ShooterTrait{
protected static int timerIndex = 0;
protected static final int timerTarget = timerIndex++;
protected static final int timerReload = timerIndex++;
protected static final Array<Tile> nearbyCores = new Array<>();
protected static final int timerShootLeft = timerIndex++;
protected static final int timerShootRight = timerIndex++;
protected UnitType type;
protected Timer timer = new Timer(5);
@@ -55,7 +52,10 @@ public abstract class BaseUnit extends Unit{
protected Squad squad;
protected int spawner = -1;
public BaseUnit(UnitType type, Team team){
/**Initialize the type and team of this unit. Only call once!*/
public void init(UnitType type, Team team){
if(this.type != null) throw new RuntimeException("This unit is already initialized!");
this.type = type;
this.team = team;
}
@@ -111,11 +111,6 @@ public abstract class BaseUnit extends Unit{
target = null;
}
}
public void shoot(AmmoType type, float rotation){
CallEntity.onUnitShoot(this, type, rotation);
}
public void targetClosestAllyFlag(BlockFlag flag){
if(target != null) return;
@@ -154,9 +149,24 @@ public abstract class BaseUnit extends Unit{
return null;
}
@Override
public Timer getTimer() {
return timer;
}
@Override
public int getShootTimer(boolean left) {
return left ? timerShootLeft : timerShootRight;
}
@Override
public Weapon getWeapon() {
return type.weapon;
}
@Override
public TextureRegion getIconRegion() {
return Draw.region(type.name);
return type.iconRegion;
}
@Override
@@ -195,12 +205,12 @@ public abstract class BaseUnit extends Unit{
@Override
public boolean acceptsAmmo(Item item) {
return type.ammo.containsKey(item) && inventory.canAcceptAmmo(type.ammo.get(item));
return getWeapon().getAmmoType(item) != null && inventory.canAcceptAmmo(getWeapon().getAmmoType(item));
}
@Override
public void addAmmo(Item item) {
inventory.addAmmo(type.ammo.get(item));
inventory.addAmmo(getWeapon().getAmmoType(item));
}
@Override
@@ -340,19 +350,6 @@ public abstract class BaseUnit extends Unit{
super.onDeath();
}
@Remote(called = Loc.server, in = In.entities)
public static void onUnitShoot(BaseUnit unit, AmmoType type, float rotation){
if(unit == null) return;
Bullet.create(type.bullet, unit,
unit.x + Angles.trnsx(rotation, unit.type.shootTranslation),
unit.y + Angles.trnsy(rotation, unit.type.shootTranslation), rotation);
Effects.effect(type.shootEffect, unit.x + Angles.trnsx(rotation, unit.type.shootTranslation),
unit.y + Angles.trnsy(rotation, unit.type.shootTranslation), rotation, unit);
Effects.effect(type.smokeEffect, unit.x + Angles.trnsx(rotation, unit.type.shootTranslation),
unit.y + Angles.trnsy(rotation, unit.type.shootTranslation), rotation, unit);
}
@Remote(called = Loc.server, in = In.entities)
public static void onUnitDeath(BaseUnit unit){
if(unit == null) return;
@@ -5,9 +5,9 @@ import io.anuke.mindustry.entities.Predict;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.traits.CarriableTrait;
import io.anuke.mindustry.entities.traits.CarryTrait;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Trail;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.ItemStack;
import io.anuke.mindustry.world.Tile;
@@ -29,10 +29,6 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
protected Trail trail = new Trail(8);
protected CarriableTrait carrying;
public FlyingUnit(UnitType type, Team team) {
super(type, team);
}
//instantiation only
public FlyingUnit(){
@@ -60,6 +56,8 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
updateRotation();
trail.update(x + Angles.trnsx(rotation + 180f, 6f) + Mathf.range(wobblyness),
y + Angles.trnsy(rotation + 180f, 6f) + Mathf.range(wobblyness));
wobble();
}
@Override
@@ -114,15 +112,15 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
return 60;
}
@Override
public void removed() {
dropCarry();
}
protected void wobble(){
if(Net.client()) return;
@Override
public void onDeath() {
super.onDeath();
dropCarry();
x += Mathf.sin(Timers.time() + id * 999, 25f, 0.07f);
y += Mathf.cos(Timers.time() + id * 999, 25f, 0.07f);
if (velocity.len() <= 0.2f) {
rotation += Mathf.sin(Timers.time() + id * 99, 10f, 8f);
}
}
protected void updateRotation(){
@@ -237,14 +235,14 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
}else{
attack(150f);
if (timer.get(timerReload, type.reload) && Mathf.angNear(angleTo(target), rotation, 13f)
if ((Mathf.angNear(angleTo(target), rotation, 15f) || !inventory.getAmmo().bullet.keepVelocity) //bombers don't care about rotation
&& distanceTo(target) < inventory.getAmmo().getRange()) {
AmmoType ammo = inventory.getAmmo();
inventory.useAmmo();
Vector2 to = Predict.intercept(FlyingUnit.this, target, ammo.bullet.speed);
shoot(ammo, Angles.moveToward(rotation, angleTo(to.x, to.y), maxAim));
getWeapon().update(FlyingUnit.this, to.x, to.y);
}
}
}
@@ -8,6 +8,8 @@ import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.Upgrade;
import io.anuke.mindustry.type.Weapon;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.mindustry.world.meta.BlockFlag;
@@ -18,21 +20,26 @@ import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import static io.anuke.mindustry.Vars.world;
public abstract class GroundUnit extends BaseUnit {
protected static Translator vec = new Translator();
protected static float maxAim = 30f;
protected static final int timerReloadAlt = timerIndex++;
protected float walkTime;
protected float baseRotation;
protected Weapon weapon;
public GroundUnit(UnitType type, Team team) {
super(type, team);
}
public GroundUnit(){
@Override
public void init(UnitType type, Team team) {
super.init(type, team);
this.weapon = type.weapon;
}
@Override
@@ -64,6 +71,11 @@ public abstract class GroundUnit extends BaseUnit {
}
}
@Override
public Weapon getWeapon() {
return weapon;
}
@Override
public void draw() {
Draw.alpha(hitTime / hitDuration);
@@ -79,7 +91,7 @@ public abstract class GroundUnit extends BaseUnit {
}
for (int i : Mathf.signs) {
Draw.rect(type.name + "-leg",
Draw.rect(type.legRegion,
x + Angles.trnsx(baseRotation, ft * i),
y + Angles.trnsy(baseRotation, ft * i),
12f * i, 12f - Mathf.clamp(ft * i, 0, 2), baseRotation - 90);
@@ -91,9 +103,17 @@ public abstract class GroundUnit extends BaseUnit {
Draw.tint(Color.WHITE);
}
Draw.rect(type.name + "-base", x, y, baseRotation- 90);
Draw.rect(type.baseRegion, x, y, baseRotation- 90);
Draw.rect(type.name, x, y, rotation -90);
Draw.rect(type.region, x, y, rotation -90);
for (int i : Mathf.signs) {
float tra = rotation - 90, trY = - weapon.getRecoil(this, i > 0) + type.weaponOffsetY;
float w = i > 0 ? -12 : 12;
Draw.rect(weapon.equipRegion,
x + Angles.trnsx(tra, type.weaponOffsetX * i, trY),
y + Angles.trnsy(tra, type.weaponOffsetX * i, trY), w, 12, rotation - 90);
}
Draw.alpha(1f);
}
@@ -114,6 +134,34 @@ public abstract class GroundUnit extends BaseUnit {
}
}
@Override
public void write(DataOutput data) throws IOException {
super.write(data);
data.writeByte(weapon.id);
}
@Override
public void read(DataInput data, long time) throws IOException {
super.read(data, time);
weapon = Upgrade.getByID(data.readByte());
}
@Override
public void writeSave(DataOutput stream) throws IOException {
stream.writeByte(weapon.id);
super.writeSave(stream);
}
@Override
public void readSave(DataInput stream) throws IOException{
weapon = Upgrade.getByID(weapon.id);
super.readSave(stream);
}
public void setWeapon(Weapon weapon){
this.weapon = weapon;
}
protected void moveToCore(){
Tile tile = world.tileWorld(x, y);
if(tile == null) return;
@@ -191,15 +239,13 @@ public abstract class GroundUnit extends BaseUnit {
rotate(angleTo(target));
}
if (timer.get(timerReload, type.reload) && Mathf.angNear(angleTo(target), rotation, 13f)
&& distanceTo(target) < inventory.getAmmo().getRange()) {
if (Mathf.angNear(angleTo(target), rotation, 13f) && distanceTo(target) < inventory.getAmmo().getRange()) {
AmmoType ammo = inventory.getAmmo();
inventory.useAmmo();
rotate(angleTo(target));
Vector2 to = Predict.intercept(GroundUnit.this, target, ammo.bullet.speed);
shoot(ammo, Angles.moveToward(rotation, angleTo(to.x, to.y), maxAim));
getWeapon().update(GroundUnit.this, to.x, to.y);
}
}else{
moveToCore();
@@ -1,16 +1,22 @@
package io.anuke.mindustry.entities.units;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.content.Weapons;
import io.anuke.mindustry.entities.traits.TypeTrait;
import io.anuke.mindustry.game.Content;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.game.UnlockableContent;
import io.anuke.mindustry.type.Weapon;
import io.anuke.ucore.function.Supplier;
import io.anuke.ucore.graphics.Draw;
public class UnitType {
//TODO merge unit type with mech
public class UnitType implements UnlockableContent{
private static byte lastid = 0;
private static Array<UnitType> types = new Array<>();
protected final UnitCreator creator;
protected final Supplier<? extends BaseUnit> constructor;
public final String name;
public final byte id;
@@ -21,7 +27,6 @@ public class UnitType {
public float speed = 0.4f;
public float range = 160;
public float rotatespeed = 0.1f;
public float shootTranslation = 4f;
public float baseRotateSpeed = 0.1f;
public float mass = 1f;
public boolean isFlying;
@@ -34,35 +39,58 @@ public class UnitType {
public int ammoCapacity = 100;
public int itemCapacity = 30;
public int mineLevel = 2;
public ObjectMap<Item, AmmoType> ammo = new ObjectMap<>();
public Weapon weapon = Weapons.blaster;
public float weaponOffsetX, weaponOffsetY;
public UnitType(String name, UnitCreator creator){
public TextureRegion iconRegion, legRegion, baseRegion, region;
public <T extends BaseUnit> UnitType(String name, Class<T> type, Supplier<T> mainConstructor){
this.id = lastid++;
this.name = name;
this.creator = creator;
this.constructor = mainConstructor;
types.add(this);
TypeTrait.registerType(type, mainConstructor);
}
public BaseUnit create(Team team){
return creator.create(team);
}
@Override
public void load() {
iconRegion = Draw.region("unit-icon-" + name);
region = Draw.region(name);
protected void setAmmo(AmmoType... types){
for(AmmoType type : types){
ammo.put(type.item, type);
if(!isFlying) {
legRegion = Draw.region(name + "-leg");
baseRegion = Draw.region(name + "-base");
}
}
public interface UnitCreator{
BaseUnit create(Team team);
@Override
public String getContentTypeName() {
return "unit-type";
}
@Override
public String getContentName() {
return name;
}
@Override
public Array<? extends Content> getAll() {
return types;
}
public BaseUnit create(Team team){
BaseUnit unit = constructor.get();
unit.init(this, team);
return unit;
}
public static UnitType getByID(byte id){
return types.get(id);
}
public static Array<UnitType> getAllTypes(){
public static Array<UnitType> all(){
return types;
}
}
@@ -12,9 +12,7 @@ import io.anuke.mindustry.entities.traits.BuilderTrait;
import io.anuke.mindustry.entities.units.BaseUnit;
import io.anuke.mindustry.entities.units.FlyingUnit;
import io.anuke.mindustry.entities.units.UnitState;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.mindustry.game.EventType.BlockBuildEvent;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.gen.CallEntity;
import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.type.Item;
@@ -41,8 +39,6 @@ import java.io.IOException;
import static io.anuke.mindustry.Vars.*;
public class Drone extends FlyingUnit implements BuilderTrait {
public static int typeID = -1;
protected static ObjectSet<Item> toMine;
protected static float healSpeed = 0.1f;
protected static float discoverRange = 120f;
@@ -71,19 +67,14 @@ public class Drone extends FlyingUnit implements BuilderTrait {
}
}
});
initialized = true;
}
{
initEvents();
}
public Drone(UnitType type, Team team) {
super(type, team);
}
public Drone(){
}
private void notifyPlaced(BuildEntity entity){
float timeToBuild = entity.recipe.cost;
float dist = Math.min(entity.distanceTo(x, y) - placeDistance, 0);
@@ -94,11 +85,6 @@ public class Drone extends FlyingUnit implements BuilderTrait {
}
}
@Override
public int getTypeID() {
return typeID;
}
@Override
public float getBuildPower(Tile tile) {
return 0.3f;
@@ -231,7 +217,9 @@ public class Drone extends FlyingUnit implements BuilderTrait {
build = new UnitState(){
public void entered() {
target = null;
if(!(target instanceof BuildEntity)){
target = null;
}
}
public void update() {
@@ -310,6 +298,12 @@ public class Drone extends FlyingUnit implements BuilderTrait {
findItem();
}
//core full
if(targetItem != null && entity.tile.block().acceptStack(targetItem, 1, entity.tile, Drone.this) == 0){
setState(repair);
return;
}
//if inventory is full, drop it off.
if(inventory.isFull()){
setState(drop);
@@ -395,10 +389,12 @@ public class Drone extends FlyingUnit implements BuilderTrait {
TileEntity tile = (TileEntity)target;
if(distanceTo(target) < type.range
&& tile.tile.block().acceptStack(inventory.getItem().item, inventory.getItem().amount, tile.tile, Drone.this) == inventory.getItem().amount){
CallEntity.transferItemTo(inventory.getItem().item, inventory.getItem().amount, x, y, tile.tile);
inventory.clearItem();
if(distanceTo(target) < type.range){
if(tile.tile.block().acceptStack(inventory.getItem().item, inventory.getItem().amount, tile.tile, Drone.this) == inventory.getItem().amount) {
CallEntity.transferItemTo(inventory.getItem().item, inventory.getItem().amount, x, y, tile.tile);
inventory.clearItem();
}
setState(repair);
}
@@ -0,0 +1,7 @@
package io.anuke.mindustry.entities.units.types;
import io.anuke.mindustry.entities.units.FlyingUnit;
public class Monsoon extends FlyingUnit {
}
@@ -1,22 +1,7 @@
package io.anuke.mindustry.entities.units.types;
import io.anuke.mindustry.entities.units.GroundUnit;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.mindustry.game.Team;
public class Scout extends GroundUnit {
public static int typeID = -1;
public Scout(UnitType type, Team team) {
super(type, team);
}
public Scout(){
}
@Override
public int getTypeID() {
return typeID;
}
}
@@ -0,0 +1,7 @@
package io.anuke.mindustry.entities.units.types;
import io.anuke.mindustry.entities.units.GroundUnit;
public class Titan extends GroundUnit{
}
@@ -1,55 +1,7 @@
package io.anuke.mindustry.entities.units.types;
import io.anuke.mindustry.entities.units.FlyingUnit;
import io.anuke.mindustry.entities.units.UnitType;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.net.Net;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf;
public class Vtol extends FlyingUnit {
public static int typeID = -1;
public Vtol(UnitType type, Team team) {
super(type, team);
}
public Vtol(){
}
@Override
public int getTypeID() {
return typeID;
}
@Override
public void draw() {
Draw.alpha(hitTime / hitDuration);
Draw.rect("vtol", x, y, rotation - 90);
for(int i : Mathf.signs){
Draw.rect("vtol-booster-1", x, y, 12*i, 12, rotation - 90);
Draw.rect("vtol-booster-2", x, y, 12*i, 12, rotation - 90);
}
Draw.alpha(1f);
}
@Override
public void update() {
super.update();
if(Net.client()) return;
x += Mathf.sin(Timers.time() + id * 999, 25f, 0.07f);
y += Mathf.cos(Timers.time() + id * 999, 25f, 0.07f);
if (velocity.len() <= 0.2f) {
rotation += Mathf.sin(Timers.time() + id * 99, 10f, 8f);
}
}
}