This commit is contained in:
Anuken
2018-09-18 17:04:24 -04:00
133 changed files with 1940 additions and 4188 deletions
@@ -90,7 +90,7 @@ public class Damage{
Tile tile = world.tile(cx, cy);
if(tile != null && tile.entity != null && tile.target().getTeamID() != team.ordinal() && tile.entity.collide(hitter)){
tile.entity.collision(hitter);
Effects.effect(effect, tile.worldx(), tile.worldy());
hitter.getBulletType().hit(hitter, tile.worldx(), tile.worldy());
}
return false;
});
@@ -10,7 +10,6 @@ import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.content.fx.UnitFx;
import io.anuke.mindustry.entities.effect.ItemDrop;
import io.anuke.mindustry.entities.effect.ScorchDecal;
import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.game.Team;
@@ -102,6 +101,11 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
player.onDeath();
}
@Override
public float getDrag(){
return mech.drag;
}
@Override
public Timer getTimer(){
return timer;
@@ -217,11 +221,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
}
}
@Override
public boolean collides(SolidTrait other){
return super.collides(other) || other instanceof ItemDrop;
}
@Override
public void set(float x, float y){
this.x = x;
@@ -431,6 +430,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
//region update methods
float lastx, lasty;
@Override
public void update(){
hitTime -= Timers.delta();
@@ -53,7 +53,9 @@ public class Predict{
* See {@link #intercept(float, float, float, float, float, float, float)}.
*/
public static Vector2 intercept(TargetTrait src, TargetTrait dst, float v){
return intercept(src.getX(), src.getY(), dst.getX(), dst.getY(), dst.getVelocity().x - src.getVelocity().x, dst.getVelocity().x - src.getVelocity().y, v);
return intercept(src.getX(), src.getY(), dst.getX(), dst.getY(),
dst.getTargetVelocityX() - src.getTargetVelocityX(),
dst.getTargetVelocityY() - src.getTargetVelocityY(), v);
}
private static Vector2 quad(float a, float b, float c){
@@ -207,13 +207,15 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
/**Updates velocity and status effects.*/
public void updateVelocityStatus(float drag, float maxVelocity){
Floor floor = getFloorOn();
if(isCarried()){ //carried units do not take into account velocity normally
set(carrier.getX(), carrier.getY());
velocity.set(carrier.getVelocity());
return;
}
Floor floor = getFloorOn();
Tile tile = world.tileWorld(x, y);
status.update(this);
@@ -5,6 +5,7 @@ import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.traits.AbsorbTrait;
import io.anuke.mindustry.entities.traits.SyncTrait;
import io.anuke.mindustry.entities.traits.TeamTrait;
import io.anuke.mindustry.game.Team;
@@ -15,6 +16,7 @@ import io.anuke.ucore.entities.impl.BulletEntity;
import io.anuke.ucore.entities.trait.Entity;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.ucore.entities.trait.VelocityTrait;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Pooling;
import io.anuke.ucore.util.Timer;
@@ -22,13 +24,12 @@ import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import static io.anuke.mindustry.Vars.bulletGroup;
import static io.anuke.mindustry.Vars.content;
import static io.anuke.mindustry.Vars.world;
import static io.anuke.mindustry.Vars.*;
public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncTrait{
public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncTrait, AbsorbTrait{
private static Vector2 vector = new Vector2();
public Timer timer = new Timer(3);
private float lifeScl;
private Team team;
private Object data;
private boolean supressCollision, supressOnce, initialized;
@@ -37,23 +38,23 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
public Bullet(){
}
public static void create(BulletType type, TeamTrait owner, float x, float y, float angle){
create(type, owner, owner.getTeam(), x, y, angle);
public static Bullet create(BulletType type, TeamTrait owner, float x, float y, float angle){
return create(type, owner, owner.getTeam(), x, y, angle);
}
public static void create(BulletType type, Entity owner, Team team, float x, float y, float angle){
create(type, owner, team, x, y, angle, 1f);
public static Bullet create(BulletType type, Entity owner, Team team, float x, float y, float angle){
return create(type, owner, team, x, y, angle, 1f);
}
public static void create(BulletType type, Entity owner, Team team, float x, float y, float angle, float velocityScl){
create(type, owner, team, x, y, angle, velocityScl, 1f, null);
public static Bullet create(BulletType type, Entity owner, Team team, float x, float y, float angle, float velocityScl){
return create(type, owner, team, x, y, angle, velocityScl, 1f, null);
}
public static void create(BulletType type, Entity owner, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl){
create(type, owner, team, x, y, angle, velocityScl, lifetimeScl, null);
public static Bullet create(BulletType type, Entity owner, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl){
return create(type, owner, team, x, y, angle, velocityScl, lifetimeScl, null);
}
public static void create(BulletType type, Entity owner, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl, Object data){
public static Bullet create(BulletType type, Entity owner, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl, Object data){
Bullet bullet = Pooling.obtain(Bullet.class, Bullet::new);
bullet.type = type;
bullet.owner = owner;
@@ -67,7 +68,7 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
bullet.team = team;
bullet.type = type;
bullet.time(type.lifetime() * (1f - lifetimeScl));
bullet.lifeScl = lifetimeScl;
//translate bullets backwards, purely for visual reasons
float backDelta = Timers.delta();
@@ -78,14 +79,15 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
bullet.set(x, y);
bullet.add();
return bullet;
}
public static void create(BulletType type, Bullet parent, float x, float y, float angle){
create(type, parent.owner, parent.team, x, y, angle);
public static Bullet create(BulletType type, Bullet parent, float x, float y, float angle){
return create(type, parent.owner, parent.team, x, y, angle);
}
public static void create(BulletType type, Bullet parent, float x, float y, float angle, float velocityScl){
create(type, parent.owner, parent.team, x, y, angle, velocityScl);
public static Bullet create(BulletType type, Bullet parent, float x, float y, float angle, float velocityScl){
return create(type, parent.owner, parent.team, x, y, angle, velocityScl);
}
@Remote(called = Loc.server)
@@ -107,6 +109,10 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
remove();
}
public BulletType getBulletType(){
return type;
}
public void resetOwner(Entity entity, Team team){
this.owner = entity;
this.team = team;
@@ -124,6 +130,11 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
this.data = data;
}
@Override
public float drawSize(){
return type.drawSize;
}
@Override
public float getDamage(){
if(owner instanceof Unit){
@@ -168,11 +179,6 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
type.draw(this);
}
@Override
public float drawSize(){
return 8;
}
@Override
public boolean collides(SolidTrait other){
return type.collides && super.collides(other) && !supressCollision;
@@ -225,6 +231,9 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
@Override
protected void updateLife(){
time += Timers.delta() * 1f/(lifeScl);
time = Mathf.clamp(time, 0, type.lifetime());
if(time >= type.lifetime){
if(!supressCollision) type.despawned(this);
remove();
@@ -235,6 +244,7 @@ public class Bullet extends BulletEntity<BulletType> implements TeamTrait, SyncT
public void reset(){
super.reset();
timer.clear();
lifeScl = 1f;
team = null;
data = null;
supressCollision = false;
@@ -1,250 +0,0 @@
package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Pool.Poolable;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.content.fx.UnitFx;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.traits.SaveTrait;
import io.anuke.mindustry.entities.traits.SyncTrait;
import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.net.Interpolator;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.SolidEntity;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.ucore.entities.trait.TimeTrait;
import io.anuke.ucore.entities.trait.VelocityTrait;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import static io.anuke.mindustry.Vars.*;
public class ItemDrop extends SolidEntity implements SaveTrait, SyncTrait, DrawTrait, VelocityTrait, TimeTrait, TargetTrait, Poolable{
private static final float sinkLifetime = 80f;
private Interpolator interpolator = new Interpolator();
private Item item;
private int amount;
private Vector2 velocity = new Vector2();
private float time;
private float sinktime;
/**
* Internal use only!
*/
public ItemDrop(){
hitbox.setSize(5f);
hitboxTile.setSize(5f);
}
public static ItemDrop create(Item item, int amount, float x, float y, float angle){
ItemDrop drop = new ItemDrop();
drop.item = item;
drop.amount = amount;
drop.velocity.set(4f, 0f).rotate(angle);
drop.setNet(x, y);
drop.add();
return drop;
}
public static void create(Item item, int amount, float x, float y, float velocityX, float velocityY){
create(item, amount, x, y, 0).getVelocity().set(velocityX, velocityY);
}
@Remote(called = Loc.server)
public static void onPickup(int itemid){
ItemDrop drop = itemGroup.getByID(itemid);
if(drop != null){
Effects.effect(UnitFx.pickup, drop);
}
itemGroup.removeByID(itemid);
if(Net.client()){
netClient.addRemovedEntity(itemid);
}
}
public Item getItem(){
return item;
}
public int getAmount(){
return amount;
}
@Override
public boolean isDead(){
return !isAdded();
}
@Override
public Team getTeam(){
return Team.none;
}
@Override
public float lifetime(){
return 60 * 60;
}
@Override
public void time(float time){
this.time = time;
}
@Override
public float time(){
return time;
}
@Override
public Vector2 getVelocity(){
return velocity;
}
@Override
public boolean collides(SolidTrait other){
return other instanceof Player && time > 20f;
}
@Override
public void collision(SolidTrait other, float x, float y){
Unit player = (Unit) other;
if(player.inventory.canAcceptItem(item, 1)){
int used = Math.min(amount, player.inventory.capacity() - player.inventory.getItem().amount);
player.inventory.addItem(item, used);
amount -= used;
if(amount <= 0){
Call.onPickup(getID());
}
}
}
@Override
public void draw(){
float size = itemSize * (1f - sinktime / sinkLifetime) * (1f - Mathf.curve(fin(), 0.98f));
Tile tile = world.tileWorld(x, y);
Draw.color(Color.WHITE, tile == null || !tile.floor().isLiquid ? Color.WHITE : tile.floor().liquidColor, sinktime / sinkLifetime);
Draw.rect(item.region, x, y, size, size);
int stored = Mathf.clamp(amount / 6, 1, 8);
for(int i = 0; i < stored; i++){
float px = stored == 1 ? 0 : (int)Mathf.randomSeedRange(i + 1, 4f);
float py = stored == 1 ? 0 : (int)Mathf.randomSeedRange(i + 2, 4f);
Draw.rect(item.region, x + px, y + py, size, size);
}
Draw.color();
}
@Override
public void update(){
if(Net.client()){
interpolate();
}else{
updateVelocity(0.2f);
updateTime();
if(time >= lifetime()){
Call.onPickup(getID());
}
}
Tile tile = world.tileWorld(x, y);
if(tile != null && tile.solid()){
Call.onPickup(getID());
}
if(tile != null && tile.floor().isLiquid){
sinktime += Timers.delta();
if(Mathf.chance(0.04 * Timers.delta())){
Effects.effect(tile.floor().drownUpdateEffect, tile.floor().liquidColor, x, y);
}
if(sinktime >= sinkLifetime){
remove();
}
}else{
sinktime = 0f;
}
}
@Override
public void reset(){
time = 0f;
interpolator.reset();
}
@Override
public Interpolator getInterpolator(){
return interpolator;
}
@Override
public float drawSize(){
return 10;
}
@Override
public float fin() {
return time()/lifetime();
}
@Override
public EntityGroup targetGroup(){
return itemGroup;
}
@Override
public void writeSave(DataOutput data) throws IOException{
data.writeFloat(x);
data.writeFloat(y);
data.writeByte(item.id);
data.writeShort(amount);
}
@Override
public void readSave(DataInput data) throws IOException{
x = data.readFloat();
y = data.readFloat();
item = content.item(data.readByte());
amount = data.readShort();
add();
}
@Override
public void write(DataOutput data) throws IOException{
data.writeFloat(x);
data.writeFloat(y);
data.writeByte(item.id);
data.writeShort(amount);
}
@Override
public void read(DataInput data, long time) throws IOException{
interpolator.read(x, y, data.readFloat(), data.readFloat(), time);
item = content.item(data.readByte());
amount = data.readShort();
}
}
@@ -9,7 +9,9 @@ import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.traits.AbsorbTrait;
import io.anuke.mindustry.entities.traits.SyncTrait;
import io.anuke.mindustry.entities.traits.TeamTrait;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Palette;
@@ -17,9 +19,10 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.TimedEntity;
import io.anuke.ucore.entities.impl.SolidEntity;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.ucore.entities.trait.TimeTrait;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles;
@@ -34,17 +37,24 @@ import java.io.IOException;
import static io.anuke.mindustry.Vars.bulletGroup;
import static io.anuke.mindustry.Vars.world;
public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncTrait{
private static Array<SolidTrait> entities = new Array<>();
private static Rectangle rect = new Rectangle();
private static Rectangle hitrect = new Rectangle();
public class Lightning extends SolidEntity implements Poolable, DrawTrait, SyncTrait, AbsorbTrait, TeamTrait, TimeTrait{
private static final Array<SolidTrait> entities = new Array<>();
private static final Rectangle rect = new Rectangle();
private static final Rectangle hitrect = new Rectangle();
private static final float wetDamageMultiplier = 2;
private static final float step = 4f, range = 6f, attractRange = 20f;
private static int lastSeed = 0;
private static float angle;
private static float wetDamageMultiplier = 2;
private Array<Vector2> lines = new Array<>();
private Color color = Palette.lancerLaser;
private Lightning parent;
private SeedRandom random = new SeedRandom();
private float damage, time;
private int activeFrame;
private Effect effect;
private Team team;
/**For pooling use only. Do not call directly!*/
public Lightning(){
@@ -57,18 +67,17 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT
/**Do not invoke!*/
@Remote(called = Loc.server)
public static void createLighting(int seed, Team team, Effect effect, Color color, float damage, float x, float y, float targetAngle, int length){
public static Lightning createLighting(int seed, Team team, Effect effect, Color color, float damage, float x, float y, float targetAngle, int length){
Lightning l = Pooling.obtain(Lightning.class, Lightning::new);
l.x = x;
l.y = y;
l.damage = damage;
l.effect = effect;
l.team = team;
l.random.setSeed(seed);
l.color = color;
float step = 4f;
float range = 6f;
float attractRange = 20f;
angle = targetAngle;
entities.clear();
@@ -77,10 +86,8 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT
for(int i = 0; i < length; i++){
l.lines.add(new Vector2(x, y));
float fx = x, fy = y;
float x2 = x + Angles.trnsx(angle, step);
float y2 = y + Angles.trnsy(angle, step);
float fangle = angle;
angle += Mathf.range(15f);
rect.setSize(attractRange).setCenter(x, y);
@@ -90,32 +97,11 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT
if(dst < attractRange){
angle = Mathf.slerp(angle, Angles.angle(x2, y2, entity.x, entity.y), (attractRange - dst) / attractRange / 4f);
}
entity.getHitbox(hitrect);
hitrect.x -= range / 2f;
hitrect.y -= range / 2f;
hitrect.width += range / 2f;
hitrect.height += range / 2f;
if(hitrect.contains(x2, y2) || hitrect.contains(fx, fy)){
float result = damage;
if(entity.hasEffect(StatusEffects.wet))
result = (result * wetDamageMultiplier);
entity.damage(result);
Effects.effect(effect, x2, y2, fangle);
}
});
if(l.random.chance(0.1f)){
createLighting(l.random.nextInt(), team, effect, color, damage, x2, y2, angle + l.random.range(30f), length / 3);
}
Tile tile = world.tileWorld(x, y);
if(tile != null && tile.entity != null && tile.getTeamID() != team.ordinal()){
Effects.effect(effect, x, y, fangle);
tile.entity.damage(damage/4f);
createLighting(l.random.nextInt(), team, effect, color, damage, x2, y2, angle + l.random.range(30f), length / 3)
.parent = l;
}
x = x2;
@@ -124,6 +110,41 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT
l.lines.add(new Vector2(x, y));
l.add();
return l;
}
@Override
public void absorb(){
activeFrame = 99;
if(parent != null){
parent.absorb();
}
}
@Override
public boolean collides(SolidTrait other){
return false;
}
@Override
public void time(float time){
this.time = time;
}
@Override
public boolean canBeAbsorbed(){
return activeFrame < 3;
}
@Override
public float time(){
return time;
}
@Override
public float fin(){
return time/lifetime();
}
@Override
@@ -146,11 +167,45 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT
return 10;
}
@Override
public Team getTeam(){
return team;
}
@Override
public void update(){
updateTime();
if(activeFrame == 2){
for(Vector2 vec : lines){
rect.setSize(range).setCenter(x, y);
Units.getNearbyEnemies(team, rect, unit -> {
unit.getHitbox(hitrect);
if(rect.overlaps(hitrect)){
unit.damage(damage * (unit.hasEffect(StatusEffects.wet) ? 2f : 1f));
Effects.effect(effect, vec.x, vec.y, 0f);
}
});
Tile tile = world.tileWorld(vec.x, vec.y);
if(tile != null && tile.entity != null && tile.getTeamID() != team.ordinal()){
Effects.effect(effect, vec.x, vec.y, 0f);
tile.entity.damage(damage/4f);
}
}
}
activeFrame ++;
}
@Override
public void reset(){
super.reset();
time = 0f;
color = Palette.lancerLaser;
lines.clear();
parent = null;
activeFrame = 0;
}
@Override
@@ -159,6 +214,11 @@ public class Lightning extends TimedEntity implements Poolable, DrawTrait, SyncT
Pooling.free(this);
}
@Override
public float getDamage(){
return damage/10f;
}
@Override
public void draw(){
float lx = x, ly = y;
@@ -0,0 +1,12 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.ucore.entities.trait.DamageTrait;
import io.anuke.ucore.entities.trait.Entity;
public interface AbsorbTrait extends Entity, TeamTrait, DamageTrait{
void absorb();
default boolean canBeAbsorbed(){
return true;
}
}
@@ -24,10 +24,7 @@ import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
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 io.anuke.ucore.util.Translator;
import io.anuke.ucore.util.*;
import java.io.DataInput;
import java.io.DataOutput;
@@ -184,12 +181,7 @@ public interface BuilderTrait extends Entity{
setMineTile(null);
}
TileEntity core = unit.getClosestCore();
//if there is no core to build with, stop building!
if(core == null){
return;
}
Tile tile = world.tile(current.x, current.y);
@@ -208,6 +200,13 @@ public interface BuilderTrait extends Entity{
}
}
TileEntity core = unit.getClosestCore();
//if there is no core to build with, stop building!
if(core == null){
return;
}
//otherwise, update it.
BuildEntity entity = tile.entity();
@@ -238,19 +237,26 @@ public interface BuilderTrait extends Entity{
/**Do not call directly.*/
default void updateMining(Unit unit){
Tile tile = getMineTile();
TileEntity core = unit.getClosestCore();
if(tile.block() != Blocks.air || unit.distanceTo(tile.worldx(), tile.worldy()) > mineDistance || !unit.inventory.canAcceptItem(tile.floor().drops.item)){
if(core == null || tile.block() != Blocks.air || unit.distanceTo(tile.worldx(), tile.worldy()) > mineDistance || !unit.inventory.canAcceptItem(tile.floor().drops.item)){
setMineTile(null);
}else{
Item item = tile.floor().drops.item;
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(tile.worldx(), tile.worldy()), 0.4f);
if(unit.inventory.canAcceptItem(item) &&
Mathf.chance(Timers.delta() * (0.06 - item.hardness * 0.01) * getMinePower())){
Call.transferItemToUnit(item,
if(Mathf.chance(Timers.delta() * (0.06 - item.hardness * 0.01) * getMinePower())){
if(unit.distanceTo(core) < mineTransferRange && core.items.get(item) < core.tile.block().getMaximumAccepted(core.tile, item)){
Call.transferItemTo(item, 1,
tile.worldx() + Mathf.range(tilesize / 2f),
tile.worldy() + Mathf.range(tilesize / 2f), core.tile);
}else if(unit.inventory.canAcceptItem(item)){
Call.transferItemToUnit(item,
tile.worldx() + Mathf.range(tilesize / 2f),
tile.worldy() + Mathf.range(tilesize / 2f),
unit);
}
}
if(Mathf.chance(0.06 * Timers.delta())){
@@ -2,6 +2,7 @@ package io.anuke.mindustry.entities.traits;
import io.anuke.mindustry.game.Team;
import io.anuke.ucore.entities.trait.PosTrait;
import io.anuke.ucore.entities.trait.SolidTrait;
import io.anuke.ucore.entities.trait.VelocityTrait;
/**
@@ -13,6 +14,22 @@ public interface TargetTrait extends PosTrait, VelocityTrait{
Team getTeam();
default float getTargetVelocityX(){
if(this instanceof SolidTrait){
return getX() - ((SolidTrait) this).lastPosition().x;
}else{
return getVelocity().x;
}
}
default float getTargetVelocityY(){
if(this instanceof SolidTrait){
return getY() - ((SolidTrait) this).lastPosition().y;
}else{
return getVelocity().y;
}
}
/**
* Whether this entity is a valid target.
*/
@@ -82,6 +82,11 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
threads.runDelay(unit::remove);
}
@Override
public float getDrag(){
return type.drag;
}
/**Called when a command is recieved from the command center.*/
public abstract void onCommand(UnitCommand command);
@@ -136,11 +136,13 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
public void update(){
super.update();
updateRotation();
if(!Net.client()){
updateRotation();
wobble();
}
trail.update(x + Angles.trnsx(rotation + 180f, 6f) + Mathf.range(wobblyness),
y + Angles.trnsy(rotation + 180f, 6f) + Mathf.range(wobblyness));
wobble();
}
@Override
@@ -185,11 +187,11 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
protected void wobble(){
if(Net.client()) return;
x += Mathf.sin(Timers.time() + id * 999, 25f, 0.07f)*Timers.delta();
y += Mathf.cos(Timers.time() + id * 999, 25f, 0.07f)*Timers.delta();
x += Mathf.sin(Timers.time() + id * 999, 25f, 0.08f)*Timers.delta();
y += Mathf.cos(Timers.time() + id * 999, 25f, 0.08f)*Timers.delta();
if(velocity.len() <= 0.05f){
rotation += Mathf.sin(Timers.time() + id * 99, 10f, 5f)*Timers.delta();
rotation += Mathf.sin(Timers.time() + id * 99, 10f, 2.5f)*Timers.delta();
}
}
@@ -2,30 +2,40 @@ package io.anuke.mindustry.entities.units;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.entities.effect.ItemDrop;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.type.Item;
import io.anuke.ucore.util.Mathf;
public class UnitDrops{
private static final int maxItems = 200;
private static Item[] dropTable;
public static void dropItems(BaseUnit unit){
if(Vars.itemGroup.size() > maxItems || unit.getTeam() != Team.red){
//items only dropped in waves for enemy team
if(unit.getTeam() != Vars.waveTeam || Vars.state.mode.disableWaves){
return;
}
TileEntity core = unit.getClosestEnemyCore();
if(core == null){
return;
}
if(dropTable == null){
dropTable = new Item[]{Items.densealloy, Items.lead, Items.copper};
dropTable = new Item[]{Items.densealloy, Items.silicon, Items.lead, Items.copper};
}
for(int i = 0; i < 3; i++){
for(Item item : dropTable){
//only drop unlocked items
if(!Vars.headless && !Vars.control.database().isUnlocked(item)){
continue;
}
if(Mathf.chance(0.03)){
int amount = Mathf.random(20, 40);
ItemDrop.create(item, amount, unit.x + Mathf.range(2f), unit.y + Mathf.range(2f),
unit.getVelocity().x + Mathf.range(3f), unit.getVelocity().y + Mathf.range(3f));
Call.transferItemTo(item, amount, unit.x + Mathf.range(2f), unit.y + Mathf.range(2f), core.tile);
}
}
}
@@ -41,7 +41,7 @@ public class UnitType extends UnlockableContent{
public float carryWeight = 1f;
public int itemCapacity = 30;
public ObjectSet<Item> toMine = ObjectSet.with(Items.lead, Items.copper);
public float buildPower = 0.3f, minePower = 0.7f, healSpeed = 0.1f;
public float buildPower = 0.3f, minePower = 0.7f, healSpeed = 2f;
public Weapon weapon = Weapons.blaster;
public float weaponOffsetX, weaponOffsetY;
public Color trailColor = Color.valueOf("ffa665");
@@ -3,9 +3,9 @@ package io.anuke.mindustry.entities.units.types;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Queue;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.content.fx.BlockFx;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.effect.ItemDrop;
import io.anuke.mindustry.entities.traits.BuilderTrait;
import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.entities.units.BaseUnit;
@@ -23,10 +23,10 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.BuildBlock;
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
import io.anuke.mindustry.world.meta.BlockFlag;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Events;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.EntityPhysics;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Shapes;
import io.anuke.ucore.util.Angles;
@@ -43,6 +43,7 @@ import static io.anuke.mindustry.Vars.*;
public class Drone extends FlyingUnit implements BuilderTrait{
protected static float discoverRange = 120f;
protected static boolean initialized;
protected static int timerRepairEffect = timerIndex++;
protected Item targetItem;
protected Tile mineTile;
@@ -116,8 +117,11 @@ public class Drone extends FlyingUnit implements BuilderTrait{
circle(type.range);
}else{
TileEntity entity = (TileEntity) target;
entity.health += type.healSpeed * Timers.delta();
entity.health = Mathf.clamp(entity.health, 0, entity.tile.block().health);
entity.healBy(type.healSpeed * entity.tile.block().health / 100f * Timers.delta());
if(timer.get(timerRepairEffect, 30)){
Effects.effect(BlockFx.healBlockFull, Palette.heal, entity.x, entity.y, entity.tile.block().size);
}
}
}
},
@@ -152,10 +156,6 @@ public class Drone extends FlyingUnit implements BuilderTrait{
}
retarget(() -> {
if(findItemDrop()){
return;
}
if(getMineTile() == null){
findItem();
}
@@ -183,33 +183,6 @@ public class Drone extends FlyingUnit implements BuilderTrait{
setMineTile(null);
}
},
pickup = new UnitState(){
public void entered(){
target = null;
}
public void update(){
ItemDrop item = (ItemDrop) target;
if(item == null || inventory.isFull() || item.getItem().type != ItemType.material || !inventory.canAcceptItem(item.getItem(), 1)){
setState(drop);
return;
}
if(distanceTo(item) < 4){
item.collision(Drone.this, x, y);
}
//item has been picked up
if(item.getAmount() == 0){
if(!findItemDrop()){
setState(drop);
}
}
moveTo(0f);
}
},
drop = new UnitState(){
public void entered(){
target = null;
@@ -403,23 +376,6 @@ public class Drone extends FlyingUnit implements BuilderTrait{
targetItem = Mathf.findMin(type.toMine, (a, b) -> -Integer.compare(entity.items.get(a), entity.items.get(b)));
}
protected boolean findItemDrop(){
TileEntity core = getClosestCore();
if(core == null) return false;
//find nearby dropped items to pick up if applicable
ItemDrop drop = EntityPhysics.getClosest(itemGroup, x, y, 60f,
item -> core.tile.block().acceptStack(item.getItem(), item.getAmount(), core.tile, Drone.this) == item.getAmount() &&
inventory.canAcceptItem(item.getItem(), 1));
if(drop != null){
setState(pickup);
target = drop;
return true;
}
return false;
}
@Override
public boolean canCreateBlocks(){
return false;
@@ -2,6 +2,6 @@ package io.anuke.mindustry.entities.units.types;
import io.anuke.mindustry.entities.units.FlyingUnit;
public class Monsoon extends FlyingUnit{
public class Ghoul extends FlyingUnit{
}
@@ -1,5 +1,5 @@
package io.anuke.mindustry.entities.units.types;
public class Fabricator extends Drone{
public class Phantom extends Drone{
}
@@ -0,0 +1,6 @@
package io.anuke.mindustry.entities.units.types;
import io.anuke.mindustry.entities.units.FlyingUnit;
public class Revenant extends FlyingUnit{
}
@@ -0,0 +1,4 @@
package io.anuke.mindustry.entities.units.types;
public class Spirit extends Drone{
}
@@ -2,6 +2,6 @@ package io.anuke.mindustry.entities.units.types;
import io.anuke.mindustry.entities.units.FlyingUnit;
public class Interceptor extends FlyingUnit{
public class Wraith extends FlyingUnit{
}