Unit weapon rework, titan and bomber enemies added, various fixes
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user