Changed too many things to fit in commit log
This commit is contained in:
@@ -10,24 +10,26 @@ import com.badlogic.gdx.utils.Queue;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.content.Mechs;
|
||||
import io.anuke.mindustry.content.Weapons;
|
||||
import io.anuke.mindustry.content.fx.ExplosionFx;
|
||||
import io.anuke.mindustry.entities.bullet.BulletType;
|
||||
import io.anuke.mindustry.entities.effect.DamageArea;
|
||||
import io.anuke.mindustry.entities.traits.BuilderTrait;
|
||||
import io.anuke.mindustry.entities.traits.TargetTrait;
|
||||
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.net.NetEvents;
|
||||
import io.anuke.mindustry.type.*;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.types.Floor;
|
||||
import io.anuke.mindustry.world.blocks.types.storage.CoreBlock.CoreEntity;
|
||||
import io.anuke.ucore.core.*;
|
||||
import io.anuke.ucore.entities.SolidEntity;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.entities.component.SolidTrait;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Fill;
|
||||
import io.anuke.ucore.graphics.Lines;
|
||||
import io.anuke.ucore.util.*;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.Timer;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
@@ -36,7 +38,7 @@ import java.nio.ByteBuffer;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Player extends Unit implements BlockBuilder {
|
||||
public class Player extends Unit implements BuilderTrait {
|
||||
private static final float walkSpeed = 1.1f;
|
||||
private static final float flySpeed = 0.4f;
|
||||
private static final float flyMaxSpeed = 3f;
|
||||
@@ -45,6 +47,8 @@ public class Player extends Unit implements BlockBuilder {
|
||||
|
||||
//region instance variables, constructor
|
||||
|
||||
public float baseRotation;
|
||||
|
||||
public String name = "name";
|
||||
public String uuid;
|
||||
public boolean isAdmin;
|
||||
@@ -58,7 +62,7 @@ public class Player extends Unit implements BlockBuilder {
|
||||
public int playerIndex = 0;
|
||||
public boolean isLocal = false;
|
||||
public Timer timer = new Timer(4);
|
||||
public Targetable target;
|
||||
public TargetTrait target;
|
||||
|
||||
private boolean respawning;
|
||||
private float walktime;
|
||||
@@ -84,7 +88,7 @@ public class Player extends Unit implements BlockBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMaxHealth() {
|
||||
public float maxHealth() {
|
||||
return 200;
|
||||
}
|
||||
|
||||
@@ -113,12 +117,6 @@ public class Player extends Unit implements BlockBuilder {
|
||||
inventory.addAmmo(weapon.getAmmoType(item));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteShoot(BulletType type, float x, float y, float rotation, short data) {
|
||||
Weapon weapon = Upgrade.getByID(Bits.getLeftByte(data));
|
||||
weapon.shoot(this, x, y, rotation, Bits.getRightByte(data) == 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMass(){
|
||||
return mech.mass;
|
||||
@@ -147,7 +145,7 @@ public class Player extends Unit implements BlockBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(SolidEntity other){
|
||||
public boolean collides(SolidTrait other){
|
||||
return !isDead() && super.collides(other) && !mech.flying;
|
||||
}
|
||||
|
||||
@@ -156,9 +154,6 @@ public class Player extends Unit implements BlockBuilder {
|
||||
dead = true;
|
||||
respawning = false;
|
||||
placeQueue.clear();
|
||||
if(Net.active()){
|
||||
NetEvents.handleUnitDeath(this);
|
||||
}
|
||||
|
||||
float explosiveness = 2f + (inventory.hasItem() ? inventory.getItem().item.explosiveness * inventory.getItem().amount : 0f);
|
||||
float flammability = (inventory.hasItem() ? inventory.getItem().item.flammability * inventory.getItem().amount : 0f);
|
||||
@@ -168,35 +163,35 @@ public class Player extends Unit implements BlockBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteDeath() {
|
||||
dead = true;
|
||||
respawning = false;
|
||||
Effects.effect(ExplosionFx.explosion, this);
|
||||
Effects.shake(4f, 5f, this);
|
||||
Effects.sound("die", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player set(float x, float y){
|
||||
public void set(float x, float y){
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
if(isFlying() && isLocal){
|
||||
Core.camera.position.set(x, y, 0f);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player add(){
|
||||
return add(playerGroup);
|
||||
public EntityGroup targetGroup() {
|
||||
return playerGroup;
|
||||
}
|
||||
|
||||
public void toggleTeam(){
|
||||
team = (team == Team.blue ? Team.red : Team.blue);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
//region draw methods
|
||||
|
||||
|
||||
@Override
|
||||
public void drawSmooth(){
|
||||
public float drawSize() {
|
||||
return 40;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
if((debug && (!showPlayer || !showUI)) || dead) return;
|
||||
|
||||
boolean snap = snapCamera && isLocal;
|
||||
@@ -287,15 +282,15 @@ public class Player extends Unit implements BlockBuilder {
|
||||
Draw.tscl(0.25f/2);
|
||||
layout.setText(Core.font, name);
|
||||
Draw.color(0f, 0f, 0f, 0.3f);
|
||||
Draw.rect("blank", getDrawPosition().x, getDrawPosition().y + 8 - layout.height/2, layout.width + 2, layout.height + 2);
|
||||
Draw.rect("blank", x, y + 8 - layout.height/2, layout.width + 2, layout.height + 2);
|
||||
Draw.color();
|
||||
Draw.tcolor(color);
|
||||
Draw.text(name, getDrawPosition().x, getDrawPosition().y + 8);
|
||||
Draw.text(name, x, y + 8);
|
||||
|
||||
if(isAdmin){
|
||||
Draw.color(color);
|
||||
float s = 3f;
|
||||
Draw.rect("icon-admin-small", getDrawPosition().x + layout.width/2f + 2 + 1, getDrawPosition().y + 7f, s, s);
|
||||
Draw.rect("icon-admin-small", x + layout.width/2f + 2 + 1, y + 7f, s, s);
|
||||
}
|
||||
|
||||
Draw.reset();
|
||||
@@ -574,56 +569,13 @@ public class Player extends Unit implements BlockBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpawn(ByteBuffer buffer) {
|
||||
IOUtils.writeString(buffer, name);
|
||||
buffer.put(weapon.id);
|
||||
buffer.put(mech.id);
|
||||
buffer.put(isAdmin ? 1 : (byte)0);
|
||||
buffer.putInt(Color.rgba8888(color));
|
||||
buffer.putFloat(x);
|
||||
buffer.putFloat(y);
|
||||
buffer.put((byte)team.ordinal());
|
||||
public void write(ByteBuffer buffer) {
|
||||
//todo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSpawn(ByteBuffer buffer) {
|
||||
name = IOUtils.readString(buffer);
|
||||
weapon = Upgrade.getByID(buffer.get());
|
||||
mech = Upgrade.getByID(buffer.get());
|
||||
isAdmin = buffer.get() == 1;
|
||||
color.set(buffer.getInt());
|
||||
x = buffer.getFloat();
|
||||
y = buffer.getFloat();
|
||||
team = Team.values()[buffer.get()];
|
||||
setNet(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuffer data) {
|
||||
if(Net.client() || isLocal) {
|
||||
data.putFloat(x);
|
||||
data.putFloat(y);
|
||||
}else{
|
||||
data.putFloat(interpolator.target.x);
|
||||
data.putFloat(interpolator.target.y);
|
||||
}
|
||||
data.putFloat(rotation);
|
||||
data.putFloat(baseRotation);
|
||||
data.putShort((short)health);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuffer data, long time) {
|
||||
float x = data.getFloat();
|
||||
float y = data.getFloat();
|
||||
float rot = data.getFloat();
|
||||
float baseRot = data.getFloat();
|
||||
short health = data.getShort();
|
||||
byte dashing = data.get();
|
||||
|
||||
this.health = health;
|
||||
|
||||
interpolator.read(this.x, this.y, x, y, rot, baseRot, time);
|
||||
public void read(ByteBuffer buffer, long time) {
|
||||
//todo
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.mindustry.entities.traits.TargetTrait;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
/**Class for predicting shoot angles based on velocities of targets.*/
|
||||
@@ -43,6 +44,11 @@ public class Predict {
|
||||
return sol;
|
||||
}
|
||||
|
||||
/**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);
|
||||
}
|
||||
|
||||
private static Vector2 quad(float a, float b, float c) {
|
||||
Vector2 sol = null;
|
||||
if (Math.abs(a) < 1e-6) {
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.badlogic.gdx.utils.TimeUtils;
|
||||
import io.anuke.mindustry.entities.bullet.BulletType;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.DestructibleEntity;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static io.anuke.mindustry.Vars.threads;
|
||||
|
||||
/**Base class for any entity that needs to be synced across clients.*/
|
||||
public abstract class SyncEntity extends DestructibleEntity{
|
||||
/**Interpolator, used for smoothing position.*/
|
||||
protected Interpolator interpolator = new Interpolator();
|
||||
/**smoothed position and rotation*/
|
||||
private Vector3 spos = new Vector3();
|
||||
|
||||
/**rotation of the top, usually used as the 'shoot' direction.*/
|
||||
public float rotation = 90;
|
||||
/**rotation of the base, usually leg rotation for mechs.*/
|
||||
public float baseRotation = 90;
|
||||
|
||||
/**Called when a death event is recieved remotely.*/
|
||||
public abstract void onRemoteDeath();
|
||||
|
||||
/**Called when a shoot event is recieved remotely.*/
|
||||
public abstract void onRemoteShoot(BulletType type, float x, float y, float rotation, short data);
|
||||
|
||||
//Read and write spawn data, which is sent when the entity is requested
|
||||
public abstract void writeSpawn(ByteBuffer data);
|
||||
public abstract void readSpawn(ByteBuffer data);
|
||||
|
||||
//Read and write sync data, usually position
|
||||
public abstract void write(ByteBuffer data);
|
||||
public abstract void read(ByteBuffer data, long time);
|
||||
|
||||
/**Interpolate everything needed. Should be called in update() for non-local entities.*/
|
||||
public void interpolate(){
|
||||
interpolator.update();
|
||||
|
||||
x = interpolator.pos.x;
|
||||
y = interpolator.pos.y;
|
||||
rotation = interpolator.rotation;
|
||||
baseRotation = interpolator.baseRotation;
|
||||
}
|
||||
|
||||
/**Same as draw, but for interpolated drawing at low tick speeds.*/
|
||||
public abstract void drawSmooth();
|
||||
|
||||
/**Do not override, use drawSmooth instead.*/
|
||||
@Override
|
||||
public final void draw(){
|
||||
final float x = this.x, y = this.y, rotation = this.rotation;
|
||||
|
||||
//interpolates data at low tick speeds.
|
||||
if(isSmoothing()){
|
||||
if(Vector2.dst(spos.x, spos.y, x, y) > 128){
|
||||
spos.set(x, y, rotation);
|
||||
}
|
||||
|
||||
this.x = spos.x = Mathf.lerpDelta(spos.x, x, 0.2f);
|
||||
this.y = spos.y = Mathf.lerpDelta(spos.y, y, 0.2f);
|
||||
this.rotation = spos.z = Mathf.slerpDelta(spos.z, rotation, 0.3f);
|
||||
}
|
||||
|
||||
drawSmooth();
|
||||
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
/**Returns smoothed position. x = x, y = y, z = rotation.*/
|
||||
public Vector3 getDrawPosition(){
|
||||
return isSmoothing() ? spos : spos.set(x, y, rotation);
|
||||
}
|
||||
|
||||
/**Set position and interpolator position.*/
|
||||
public <T extends SyncEntity> T setNet(float x, float y){
|
||||
set(x, y);
|
||||
interpolator.target.set(x, y);
|
||||
interpolator.last.set(x, y);
|
||||
interpolator.spacing = 1f;
|
||||
interpolator.time = 0f;
|
||||
return (T)this;
|
||||
}
|
||||
|
||||
public static boolean isSmoothing(){
|
||||
return threads.isEnabled() && threads.getFPS() <= Gdx.graphics.getFramesPerSecond() / 2f;
|
||||
}
|
||||
|
||||
public static class Interpolator {
|
||||
//used for movement
|
||||
public Vector2 target = new Vector2();
|
||||
public Vector2 last = new Vector2();
|
||||
public float targetrot, targetBaseRot;
|
||||
public float spacing = 1f;
|
||||
public float time;
|
||||
|
||||
//current state
|
||||
public Vector2 pos = new Vector2();
|
||||
public float rotation, baseRotation;
|
||||
|
||||
public void read(float cx, float cy, float x, float y, float rotation, float baseRotation, long sent){
|
||||
targetrot = rotation;
|
||||
targetBaseRot = baseRotation;
|
||||
time = 0f;
|
||||
last.set(cx, cy);
|
||||
target.set(x, y);
|
||||
spacing = Math.min(Math.max(((TimeUtils.timeSinceMillis(sent) / 1000f) * 60f), 4f), 10);
|
||||
}
|
||||
|
||||
public void update(){
|
||||
|
||||
time += 1f / spacing * Math.min(Timers.delta(), 1f);
|
||||
|
||||
time = Mathf.clamp(time, 0, 2f);
|
||||
|
||||
Mathf.lerp2(pos.set(last), target, time);
|
||||
|
||||
rotation = Mathf.slerpDelta(rotation, targetrot, 0.6f);
|
||||
baseRotation = Mathf.slerpDelta(baseRotation, targetBaseRot, 0.6f);
|
||||
|
||||
if(target.dst(pos) > 128){
|
||||
pos.set(target);
|
||||
last.set(target);
|
||||
time = 0f;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,8 @@ package io.anuke.mindustry.entities;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.mindustry.content.fx.Fx;
|
||||
import io.anuke.mindustry.entities.bullet.Bullet;
|
||||
import io.anuke.mindustry.entities.traits.TargetTrait;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.NetEvents;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.types.Wall;
|
||||
@@ -14,7 +13,8 @@ import io.anuke.mindustry.world.blocks.types.modules.LiquidModule;
|
||||
import io.anuke.mindustry.world.blocks.types.modules.PowerModule;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.Entity;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.entities.impl.BaseEntity;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.Timer;
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.io.IOException;
|
||||
import static io.anuke.mindustry.Vars.tileGroup;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class TileEntity extends Entity implements Targetable{
|
||||
public class TileEntity extends BaseEntity implements TargetTrait {
|
||||
public static final float timeToSleep = 60f*4; //4 seconds to fall asleep
|
||||
public static int sleepingEntities = 0;
|
||||
|
||||
@@ -79,7 +79,7 @@ public class TileEntity extends Entity implements Targetable{
|
||||
public void wakeUp(){
|
||||
sleepTime = 0f;
|
||||
if(sleeping){
|
||||
add(tileGroup);
|
||||
add();
|
||||
sleeping = false;
|
||||
sleepingEntities --;
|
||||
}
|
||||
@@ -91,31 +91,21 @@ public class TileEntity extends Entity implements Targetable{
|
||||
|
||||
public void write(DataOutputStream stream) throws IOException{}
|
||||
public void read(DataInputStream stream) throws IOException{}
|
||||
|
||||
|
||||
public void onDeath(){
|
||||
onDeath(false);
|
||||
}
|
||||
if(!dead) {
|
||||
dead = true;
|
||||
Block block = tile.block();
|
||||
|
||||
public void onDeath(boolean force){
|
||||
if(Net.server()){
|
||||
NetEvents.handleBlockDestroyed(this);
|
||||
block.onDestroyed(tile);
|
||||
world.removeBlock(tile);
|
||||
block.afterDestroyed(tile, this);
|
||||
remove();
|
||||
}
|
||||
|
||||
if(!Net.active() || Net.server() || force){
|
||||
|
||||
if(!dead) {
|
||||
dead = true;
|
||||
Block block = tile.block();
|
||||
|
||||
block.onDestroyed(tile);
|
||||
world.removeBlock(tile);
|
||||
block.afterDestroyed(tile, this);
|
||||
remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean collide(io.anuke.mindustry.entities.bullet.Bullet other){
|
||||
public boolean collide(Bullet other){
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -129,10 +119,6 @@ public class TileEntity extends Entity implements Targetable{
|
||||
float amount = tile.block().handleDamage(tile, damage);
|
||||
health -= amount;
|
||||
if(health <= 0) onDeath();
|
||||
|
||||
if(Net.server()){
|
||||
NetEvents.handleBlockDamaged(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -162,9 +148,9 @@ public class TileEntity extends Entity implements Targetable{
|
||||
tile.block().update(tile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TileEntity add(){
|
||||
return add(tileGroup);
|
||||
public EntityGroup targetGroup() {
|
||||
return tileGroup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,21 @@ package io.anuke.mindustry.entities;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.mindustry.content.blocks.Blocks;
|
||||
import io.anuke.mindustry.entities.bullet.Bullet;
|
||||
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.entities.traits.TeamTrait;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.game.TeamInfo.TeamData;
|
||||
import io.anuke.mindustry.net.Interpolator;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.types.Floor;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.SolidEntity;
|
||||
import io.anuke.ucore.entities.component.DrawTrait;
|
||||
import io.anuke.ucore.entities.component.SolidTrait;
|
||||
import io.anuke.ucore.entities.impl.DestructibleEntity;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
@@ -21,17 +28,39 @@ import java.io.IOException;
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public abstract class Unit extends SyncEntity implements SerializableEntity, Targetable {
|
||||
public abstract class Unit extends DestructibleEntity implements SaveTrait, TargetTrait, SyncTrait, DrawTrait, TeamTrait {
|
||||
/**total duration of hit flash effect*/
|
||||
public static final float hitDuration = 9f;
|
||||
|
||||
public StatusController status = new StatusController();
|
||||
public UnitInventory inventory = new UnitInventory(100, 100);
|
||||
public Team team = Team.blue;
|
||||
public float rotation;
|
||||
|
||||
public Vector2 velocity = new Vector2(0f, 0.0001f);
|
||||
public float hitTime;
|
||||
public float drownTime;
|
||||
protected Interpolator interpolator = new Interpolator();
|
||||
protected StatusController status = new StatusController();
|
||||
protected Team team = Team.blue;
|
||||
|
||||
protected Vector2 velocity = new Vector2(0f, 0.0001f);
|
||||
protected float hitTime;
|
||||
protected float drownTime;
|
||||
|
||||
@Override
|
||||
public Team getTeam(){
|
||||
return team;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interpolate() {
|
||||
interpolator.update();
|
||||
|
||||
x = interpolator.pos.x;
|
||||
y = interpolator.pos.y;
|
||||
rotation = interpolator.values[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Interpolator getInterpolator() {
|
||||
return interpolator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damage(float amount){
|
||||
@@ -40,7 +69,7 @@ public abstract class Unit extends SyncEntity implements SerializableEntity, Tar
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(SolidEntity other){
|
||||
public boolean collides(SolidTrait other){
|
||||
return other instanceof Bullet && state.teams.areEnemies((((Bullet) other).team), team);
|
||||
}
|
||||
|
||||
@@ -51,6 +80,11 @@ public abstract class Unit extends SyncEntity implements SerializableEntity, Tar
|
||||
status.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2 getVelocity() {
|
||||
return velocity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSave(DataOutputStream stream) throws IOException {
|
||||
stream.writeByte(team.ordinal());
|
||||
@@ -79,6 +113,10 @@ public abstract class Unit extends SyncEntity implements SerializableEntity, Tar
|
||||
this.status.set(StatusEffect.getByID(effect), etime);
|
||||
}
|
||||
|
||||
public StatusEffect getStatus(){
|
||||
return status.current();
|
||||
}
|
||||
|
||||
public TileEntity getClosestCore(){
|
||||
if(state.teams.has(team)){
|
||||
TeamData data = state.teams.get(team);
|
||||
@@ -99,10 +137,6 @@ public abstract class Unit extends SyncEntity implements SerializableEntity, Tar
|
||||
return (Floor)(tile == null || (tile.floor() == null) ? Blocks.defaultFloor : tile.floor());
|
||||
}
|
||||
|
||||
public Team getTeam(){
|
||||
return team;
|
||||
}
|
||||
|
||||
public void updateVelocityStatus(float drag, float maxVelocity){
|
||||
Floor floor = getFloorOn();
|
||||
Tile tile = world.tileWorld(x, y);
|
||||
@@ -175,11 +209,6 @@ public abstract class Unit extends SyncEntity implements SerializableEntity, Tar
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2 getVelocity() {
|
||||
return velocity;
|
||||
}
|
||||
|
||||
public void drawUnder(){}
|
||||
public void drawOver(){}
|
||||
|
||||
|
||||
@@ -3,13 +3,14 @@ package io.anuke.mindustry.entities;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.ObjectSet;
|
||||
import io.anuke.mindustry.entities.traits.TargetTrait;
|
||||
import io.anuke.mindustry.entities.units.BaseUnit;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.entities.Entities;
|
||||
import io.anuke.ucore.entities.Entity;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.entities.EntityPhysics;
|
||||
import io.anuke.ucore.entities.impl.BaseEntity;
|
||||
import io.anuke.ucore.function.Consumer;
|
||||
import io.anuke.ucore.function.Predicate;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
@@ -19,6 +20,7 @@ import static io.anuke.mindustry.Vars.*;
|
||||
/**Utility class for unit and team interactions.*/
|
||||
public class Units {
|
||||
private static Rectangle rect = new Rectangle();
|
||||
private static Rectangle hitrect = new Rectangle();
|
||||
|
||||
/**Validates a target.
|
||||
* @param target The target to validate
|
||||
@@ -28,18 +30,18 @@ public class Units {
|
||||
* @param range The maximum distance from the target X/Y the targeter can be for it to be valid
|
||||
* @return whether the target is invalid
|
||||
*/
|
||||
public static boolean invalidateTarget(Targetable target, Team team, float x, float y, float range) {
|
||||
public static boolean invalidateTarget(TargetTrait target, Team team, float x, float y, float range) {
|
||||
return target == null || (range != Float.MAX_VALUE && target.distanceTo(x, y) > range) || target.getTeam() == team || !target.isValid();
|
||||
|
||||
}
|
||||
|
||||
/**See {@link #invalidateTarget(Targetable, Team, float, float, float)}*/
|
||||
public static boolean invalidateTarget(Targetable target, Team team, float x, float y){
|
||||
/**See {@link #invalidateTarget(TargetTrait, Team, float, float, float)}*/
|
||||
public static boolean invalidateTarget(TargetTrait target, Team team, float x, float y){
|
||||
return invalidateTarget(target, team, x, y, Float.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**See {@link #invalidateTarget(Targetable, Team, float, float, float)}*/
|
||||
public static boolean invalidateTarget(Targetable target, Unit targeter){
|
||||
/**See {@link #invalidateTarget(TargetTrait, Team, float, float, float)}*/
|
||||
public static boolean invalidateTarget(TargetTrait target, Unit targeter){
|
||||
return invalidateTarget(target, targeter.team, targeter.x, targeter.y, targeter.inventory.getAmmoRange());
|
||||
}
|
||||
|
||||
@@ -53,8 +55,12 @@ public class Units {
|
||||
|
||||
Units.getNearby(rect, unit -> {
|
||||
if(value[0]) return;
|
||||
if(!unit.isFlying() && unit.hitbox.getRect(unit.x, unit.y).overlaps(rect)){
|
||||
value[0] = true;
|
||||
if(!unit.isFlying()){
|
||||
unit.getHitbox(hitrect);
|
||||
|
||||
if(hitrect.overlaps(rect)) {
|
||||
value[0] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -73,7 +79,7 @@ public class Units {
|
||||
|
||||
/**Returns the neareset tile entity in a range.*/
|
||||
public static TileEntity findTile(float x, float y, float range, Predicate<Tile> pred){
|
||||
Entity closest = null;
|
||||
BaseEntity closest = null;
|
||||
float dst = 0;
|
||||
|
||||
int rad = (int)(range/tilesize)+1;
|
||||
@@ -119,7 +125,7 @@ public class Units {
|
||||
}
|
||||
|
||||
/**Returns the closest target enemy. First, units are checked, then tile entities.*/
|
||||
public static Targetable getClosestTarget(Team team, float x, float y, float range){
|
||||
public static TargetTrait getClosestTarget(Team team, float x, float y, float range){
|
||||
Unit unit = getClosestEnemy(team, x, y, range, u -> true);
|
||||
if(unit != null){
|
||||
return unit;
|
||||
@@ -179,11 +185,11 @@ public class Units {
|
||||
|
||||
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
||||
if(!group.isEmpty()){
|
||||
Entities.getNearby(group, rect, entity -> cons.accept((Unit)entity));
|
||||
EntityPhysics.getNearby(group, rect, entity -> cons.accept((Unit)entity));
|
||||
}
|
||||
|
||||
//now check all ally players
|
||||
Entities.getNearby(playerGroup, rect, player -> {
|
||||
EntityPhysics.getNearby(playerGroup, rect, player -> {
|
||||
if(((Unit)player).team == team) cons.accept((Unit)player);
|
||||
});
|
||||
}
|
||||
@@ -194,12 +200,12 @@ public class Units {
|
||||
for(Team team : Team.values()){
|
||||
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
||||
if(!group.isEmpty()){
|
||||
Entities.getNearby(group, rect, entity -> cons.accept((Unit)entity));
|
||||
EntityPhysics.getNearby(group, rect, entity -> cons.accept((Unit)entity));
|
||||
}
|
||||
}
|
||||
|
||||
//now check all enemy players
|
||||
Entities.getNearby(playerGroup, rect, player -> cons.accept((Unit)player));
|
||||
EntityPhysics.getNearby(playerGroup, rect, player -> cons.accept((Unit)player));
|
||||
}
|
||||
|
||||
/**Iterates over all units that are enemies of this team.*/
|
||||
@@ -209,12 +215,12 @@ public class Units {
|
||||
for(Team other : targets){
|
||||
EntityGroup<BaseUnit> group = unitGroups[other.ordinal()];
|
||||
if(!group.isEmpty()){
|
||||
Entities.getNearby(group, rect, entity -> cons.accept((Unit)entity));
|
||||
EntityPhysics.getNearby(group, rect, entity -> cons.accept((Unit)entity));
|
||||
}
|
||||
}
|
||||
|
||||
//now check all enemy players
|
||||
Entities.getNearby(playerGroup, rect, player -> {
|
||||
EntityPhysics.getNearby(playerGroup, rect, player -> {
|
||||
if(targets.contains(((Player)player).team)){
|
||||
cons.accept((Unit)player);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class BasicBulletType extends BulletType {
|
||||
float a = Mathf.random(360f);
|
||||
Bullet bullet = Bullet.create(fragBullet, b,
|
||||
x + Angles.trnsx(a, len), y + Angles.trnsy(a, len), a);
|
||||
bullet.velocity.scl(Mathf.random(fragVelocityMin, fragVelocityMax));
|
||||
bullet.getVelocity().scl(Mathf.random(fragVelocityMin, fragVelocityMax));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,19 @@ package io.anuke.mindustry.entities.bullet;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Pools;
|
||||
import io.anuke.mindustry.entities.SyncEntity;
|
||||
import io.anuke.mindustry.entities.Unit;
|
||||
import io.anuke.mindustry.entities.traits.TeamTrait;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.entities.BulletEntity;
|
||||
import io.anuke.ucore.entities.Entity;
|
||||
import io.anuke.ucore.entities.SolidEntity;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.entities.component.Entity;
|
||||
import io.anuke.ucore.entities.component.SolidTrait;
|
||||
import io.anuke.ucore.entities.component.VelocityTrait;
|
||||
import io.anuke.ucore.entities.impl.BulletEntity;
|
||||
import io.anuke.ucore.util.Timer;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
import static io.anuke.mindustry.Vars.bulletGroup;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class Bullet extends BulletEntity<BulletType>{
|
||||
private static Vector2 vector = new Vector2();
|
||||
@@ -19,8 +22,8 @@ public class Bullet extends BulletEntity<BulletType>{
|
||||
public Timer timer = new Timer(3);
|
||||
public Team team;
|
||||
|
||||
public static Bullet create(BulletType type, Unit owner, float x, float y, float angle){
|
||||
return create(type, owner, owner.team, 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 Bullet create (BulletType type, Entity owner, Team team, float x, float y, float angle){
|
||||
@@ -29,13 +32,14 @@ public class Bullet extends BulletEntity<BulletType>{
|
||||
bullet.owner = owner;
|
||||
|
||||
bullet.velocity.set(0, type.speed).setAngle(angle);
|
||||
bullet.velocity.add(owner instanceof Unit ? ((Unit)owner).velocity : Vector2.Zero);
|
||||
bullet.velocity.add(owner instanceof VelocityTrait ? ((VelocityTrait)owner).getVelocity() : Vector2.Zero);
|
||||
bullet.hitbox.setSize(type.hitsize);
|
||||
|
||||
bullet.team = team;
|
||||
bullet.type = type;
|
||||
bullet.set(x, y);
|
||||
return bullet.add();
|
||||
bullet.add();
|
||||
return bullet;
|
||||
}
|
||||
|
||||
public static Bullet create(BulletType type, Bullet parent, float x, float y, float angle){
|
||||
@@ -43,20 +47,14 @@ public class Bullet extends BulletEntity<BulletType>{
|
||||
}
|
||||
|
||||
private Bullet(){}
|
||||
|
||||
|
||||
public boolean collidesTiles(){
|
||||
return true; //TODO make artillery and such not do this
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(){
|
||||
//interpolate position linearly at low tick speeds
|
||||
if(SyncEntity.isSmoothing()){
|
||||
x += threads.getFramesSinceUpdate() * velocity.x;
|
||||
y += threads.getFramesSinceUpdate() * velocity.y;
|
||||
|
||||
type.draw(this);
|
||||
|
||||
x -= threads.getFramesSinceUpdate() * velocity.x;
|
||||
y -= threads.getFramesSinceUpdate() * velocity.y;
|
||||
}else{
|
||||
type.draw(this);
|
||||
}
|
||||
type.draw(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,22 +62,18 @@ public class Bullet extends BulletEntity<BulletType>{
|
||||
return 8;
|
||||
}
|
||||
|
||||
public boolean collidesTiles(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(SolidEntity other){
|
||||
public boolean collides(SolidTrait other){
|
||||
return super.collides(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collision(SolidEntity other, float x, float y){
|
||||
public void collision(SolidTrait other, float x, float y){
|
||||
super.collision(other, x, y);
|
||||
|
||||
if(other instanceof Unit){
|
||||
Unit unit = (Unit)other;
|
||||
unit.velocity.add(vector.set(other.x, other.y).sub(x, y).setLength(type.knockback / unit.getMass()));
|
||||
unit.getVelocity().add(vector.set(other.getX(), other.getY()).sub(x, y).setLength(type.knockback / unit.getMass()));
|
||||
unit.applyEffect(type.status, type.statusIntensity);
|
||||
}
|
||||
}
|
||||
@@ -89,7 +83,7 @@ public class Bullet extends BulletEntity<BulletType>{
|
||||
super.update();
|
||||
|
||||
if (type.hitTiles && collidesTiles()) {
|
||||
world.raycastEach(world.toTile(lastX), world.toTile(lastY), world.toTile(x), world.toTile(y), (x, y) -> {
|
||||
world.raycastEach(world.toTile(lastPosition().x), world.toTile(lastPosition().y), world.toTile(x), world.toTile(y), (x, y) -> {
|
||||
|
||||
Tile tile = world.tile(x, y);
|
||||
if (tile == null) return false;
|
||||
@@ -108,11 +102,6 @@ public class Bullet extends BulletEntity<BulletType>{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDamage(){
|
||||
return damage == -1 ? type.damage : damage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
@@ -126,7 +115,7 @@ public class Bullet extends BulletEntity<BulletType>{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bullet add(){
|
||||
return super.add(bulletGroup);
|
||||
public EntityGroup targetGroup() {
|
||||
return bulletGroup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import io.anuke.mindustry.content.StatusEffects;
|
||||
import io.anuke.mindustry.content.fx.BulletFx;
|
||||
import io.anuke.mindustry.entities.StatusEffect;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.entities.BaseBulletType;
|
||||
import io.anuke.ucore.entities.impl.BaseBulletType;
|
||||
|
||||
public abstract class BulletType extends BaseBulletType<Bullet>{
|
||||
private static int lastid = 0;
|
||||
|
||||
@@ -15,7 +15,7 @@ import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Effects.Effect;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.SolidEntity;
|
||||
import io.anuke.ucore.entities.impl.SolidEntity;
|
||||
import io.anuke.ucore.function.Consumer;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.Physics;
|
||||
@@ -26,6 +26,7 @@ import static io.anuke.mindustry.Vars.*;
|
||||
/**Utility class for damaging in an area.*/
|
||||
public class DamageArea{
|
||||
private static Rectangle rect = new Rectangle();
|
||||
private static Rectangle hitrect = new Rectangle();
|
||||
private static Translator tr = new Translator();
|
||||
|
||||
/**Creates a dynamic explosion based on specified parameters.*/
|
||||
@@ -90,7 +91,8 @@ public class DamageArea{
|
||||
rect.height += expand*2;
|
||||
|
||||
Consumer<Unit> cons = e -> {
|
||||
Rectangle other = e.hitbox.getRect(e.x, e.y);
|
||||
e.getHitbox(hitrect);
|
||||
Rectangle other = hitrect;
|
||||
other.y -= expand;
|
||||
other.x -= expand;
|
||||
other.width += expand * 2;
|
||||
@@ -111,7 +113,8 @@ public class DamageArea{
|
||||
/**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) {
|
||||
Consumer<Unit> cons = entity -> {
|
||||
if (!entity.hitbox.getRect(entity.x, entity.y).overlaps(rect)) {
|
||||
entity.getHitbox(hitrect);
|
||||
if (!hitrect.overlaps(rect)) {
|
||||
return;
|
||||
}
|
||||
entity.damage(damage);
|
||||
@@ -140,7 +143,7 @@ public class DamageArea{
|
||||
float amount = calculateDamage(x, y, entity.x, entity.y, radius, damage);
|
||||
entity.damage(amount);
|
||||
//TODO better velocity displacement
|
||||
entity.velocity.add(tr.set(entity.x - x, entity.y - y).setLength(damage*2f));
|
||||
entity.getVelocity().add(tr.set(entity.x - x, entity.y - y).setLength(damage*2f));
|
||||
};
|
||||
|
||||
rect.setSize(radius *2).setCenter(x, y);
|
||||
|
||||
@@ -6,13 +6,15 @@ import com.badlogic.gdx.utils.Pool.Poolable;
|
||||
import com.badlogic.gdx.utils.Pools;
|
||||
import io.anuke.mindustry.content.StatusEffects;
|
||||
import io.anuke.mindustry.content.fx.EnvironmentFx;
|
||||
import io.anuke.mindustry.entities.SerializableEntity;
|
||||
import io.anuke.mindustry.entities.traits.SaveTrait;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.TimedEntity;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.entities.component.DrawTrait;
|
||||
import io.anuke.ucore.entities.impl.TimedEntity;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
@@ -22,7 +24,7 @@ import java.io.IOException;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class Fire extends TimedEntity implements SerializableEntity, Poolable{
|
||||
public class Fire extends TimedEntity implements SaveTrait, Poolable, DrawTrait {
|
||||
private static final IntMap<Fire> map = new IntMap<>();
|
||||
private static final float baseLifetime = 1000f;
|
||||
|
||||
@@ -39,7 +41,8 @@ public class Fire extends TimedEntity implements SerializableEntity, Poolable{
|
||||
fire = Pools.obtain(Fire.class);
|
||||
fire.tile = tile;
|
||||
fire.lifetime = baseLifetime;
|
||||
map.put(tile.packedPosition(), fire.add());
|
||||
fire.add();
|
||||
map.put(tile.packedPosition(), fire);
|
||||
}else{
|
||||
fire.lifetime = baseLifetime;
|
||||
fire.time = 0f;
|
||||
@@ -105,6 +108,11 @@ public class Fire extends TimedEntity implements SerializableEntity, Poolable{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float drawSize() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSave(DataOutputStream stream) throws IOException {
|
||||
stream.writeInt(tile.packedPosition());
|
||||
@@ -144,7 +152,7 @@ public class Fire extends TimedEntity implements SerializableEntity, Poolable{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fire add(){
|
||||
return add(airItemGroup);
|
||||
public EntityGroup targetGroup() {
|
||||
return airItemGroup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Effects.Effect;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.EffectEntity;
|
||||
import io.anuke.ucore.entities.impl.EffectEntity;
|
||||
import io.anuke.ucore.function.EffectRenderer;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package io.anuke.mindustry.entities.effect;
|
||||
|
||||
import com.badlogic.gdx.utils.Pools;
|
||||
import io.anuke.mindustry.entities.traits.SyncTrait;
|
||||
import io.anuke.mindustry.net.Interpolator;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.ucore.entities.component.DrawTrait;
|
||||
import io.anuke.ucore.entities.impl.SolidEntity;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class ItemDrop extends SolidEntity implements SyncTrait, DrawTrait {
|
||||
private Interpolator interpolator = new Interpolator();
|
||||
private Item item;
|
||||
|
||||
public static ItemDrop create(Item item, float x, float y){
|
||||
ItemDrop drop = Pools.obtain(ItemDrop.class);
|
||||
drop.item = item;
|
||||
drop.set(x, y);
|
||||
|
||||
return drop;
|
||||
}
|
||||
|
||||
/**Internal use only!*/
|
||||
public ItemDrop(){}
|
||||
|
||||
@Override
|
||||
public void removed() {
|
||||
Pools.free(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Interpolator getInterpolator() {
|
||||
return interpolator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float drawSize() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuffer data) {
|
||||
data.putFloat(x);
|
||||
data.putFloat(y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuffer data, long time) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,10 @@ package io.anuke.mindustry.entities.effect;
|
||||
import com.badlogic.gdx.math.Interpolation;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Pools;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.ucore.entities.Entity;
|
||||
import io.anuke.ucore.entities.TimedEntity;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.entities.impl.TimedEntity;
|
||||
import io.anuke.ucore.function.Callable;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Fill;
|
||||
@@ -15,6 +14,8 @@ import io.anuke.ucore.graphics.Lines;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.Position;
|
||||
|
||||
import static io.anuke.mindustry.Vars.effectGroup;
|
||||
|
||||
public class ItemTransfer extends TimedEntity{
|
||||
private Vector2 from = new Vector2();
|
||||
private Vector2 current = new Vector2();
|
||||
@@ -80,7 +81,7 @@ public class ItemTransfer extends TimedEntity{
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Entity> T add() {
|
||||
return super.add(Vars.effectGroup);
|
||||
public EntityGroup targetGroup() {
|
||||
return effectGroup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,24 +6,26 @@ import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Pool.Poolable;
|
||||
import com.badlogic.gdx.utils.Pools;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.content.StatusEffects;
|
||||
import io.anuke.mindustry.entities.Units;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Effects.Effect;
|
||||
import io.anuke.ucore.entities.Entity;
|
||||
import io.anuke.ucore.entities.SolidEntity;
|
||||
import io.anuke.ucore.entities.TimedEntity;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.entities.component.SolidTrait;
|
||||
import io.anuke.ucore.entities.impl.TimedEntity;
|
||||
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 static io.anuke.mindustry.Vars.bulletGroup;
|
||||
|
||||
public class Lightning extends TimedEntity implements Poolable{
|
||||
private static Array<SolidEntity> entities = new Array<>();
|
||||
private static Array<SolidTrait> entities = new Array<>();
|
||||
private static Rectangle rect = new Rectangle();
|
||||
private static Rectangle hitrect = new Rectangle();
|
||||
private static float angle;
|
||||
private static float wetDamageMultiplier = 2;
|
||||
|
||||
@@ -66,12 +68,16 @@ public class Lightning extends TimedEntity implements Poolable{
|
||||
angle = Mathf.slerp(angle, Angles.angle(x2, y2, entity.x, entity.y), (attractRange - dst) / attractRange / 4f);
|
||||
}
|
||||
|
||||
Rectangle hitbox = entity.hitbox.getRect(entity.x, entity.y, range);
|
||||
entity.getHitbox(hitrect);
|
||||
hitrect.x -= range/2f;
|
||||
hitrect.y -= range/2f;
|
||||
hitrect.width += range/2f;
|
||||
hitrect.height += range/2f;
|
||||
|
||||
if(hitbox.contains(x2, y2) || hitbox.contains(fx, fy)){
|
||||
if(hitrect.contains(x2, y2) || hitrect.contains(fx, fy)){
|
||||
float result = damage;
|
||||
|
||||
if(entity.status.current() == StatusEffects.wet)
|
||||
if(entity.getStatus() == StatusEffects.wet)
|
||||
result = (result * wetDamageMultiplier);
|
||||
|
||||
entity.damage(result);
|
||||
@@ -115,7 +121,7 @@ public class Lightning extends TimedEntity implements Poolable{
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Entity> T add() {
|
||||
return super.add(Vars.bulletGroup);
|
||||
public EntityGroup targetGroup() {
|
||||
return bulletGroup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,14 +12,16 @@ import io.anuke.mindustry.content.bullets.TurretBullets;
|
||||
import io.anuke.mindustry.content.fx.BlockFx;
|
||||
import io.anuke.mindustry.content.fx.EnvironmentFx;
|
||||
import io.anuke.mindustry.entities.bullet.Bullet;
|
||||
import io.anuke.mindustry.entities.SerializableEntity;
|
||||
import io.anuke.mindustry.entities.traits.SaveTrait;
|
||||
import io.anuke.mindustry.entities.Units;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.type.Liquid;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.Entity;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.entities.component.DrawTrait;
|
||||
import io.anuke.ucore.entities.impl.BaseEntity;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Fill;
|
||||
import io.anuke.ucore.graphics.Hue;
|
||||
@@ -34,12 +36,13 @@ import java.io.IOException;
|
||||
import static io.anuke.mindustry.Vars.puddleGroup;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class Puddle extends Entity implements SerializableEntity, Poolable{
|
||||
public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait {
|
||||
private static final IntMap<Puddle> map = new IntMap<>();
|
||||
private static final float maxLiquid = 70f;
|
||||
private static final int maxGeneration = 2;
|
||||
private static final Color tmp = new Color();
|
||||
private static final Rectangle rect = new Rectangle();
|
||||
private static final Rectangle rect2 = new Rectangle();
|
||||
private static int seeds;
|
||||
|
||||
private int loadedPosition = -1;
|
||||
@@ -83,7 +86,8 @@ public class Puddle extends Entity implements SerializableEntity, Poolable{
|
||||
puddle.liquid = liquid;
|
||||
puddle.amount = amount;
|
||||
puddle.generation = generation;
|
||||
puddle.set((tile.worldx() + source.worldx())/2f, (tile.worldy() + source.worldy())/2f).add();
|
||||
puddle.set((tile.worldx() + source.worldx())/2f, (tile.worldy() + source.worldy())/2f);
|
||||
puddle.add();
|
||||
map.put(tile.packedPosition(), puddle);
|
||||
}else if(p.liquid == liquid){
|
||||
p.accepting = Math.max(amount, p.accepting);
|
||||
@@ -153,11 +157,11 @@ public class Puddle extends Entity implements SerializableEntity, Poolable{
|
||||
|
||||
if(amount >= maxLiquid/2f && Timers.get(this, "update", 20)){
|
||||
Units.getNearby(rect.setSize(Mathf.clamp(amount/(maxLiquid/1.5f))*10f).setCenter(tile.worldx(), tile.worldy()), unit -> {
|
||||
Rectangle o = unit.hitbox.getRect(unit.x, unit.y);
|
||||
if(!rect.overlaps(o)) return;
|
||||
unit.getHitbox(rect2);
|
||||
if(!rect.overlaps(rect2)) return;
|
||||
|
||||
unit.applyEffect(liquid.effect, 0.5f);
|
||||
if(unit.velocity.len() > 0.4) {
|
||||
if(unit.getVelocity().len() > 0.4) {
|
||||
Effects.effect(BlockFx.ripple, liquid.color, unit.x, unit.y);
|
||||
}
|
||||
});
|
||||
@@ -192,6 +196,11 @@ public class Puddle extends Entity implements SerializableEntity, Poolable{
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float drawSize() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSave(DataOutputStream stream) throws IOException {
|
||||
stream.writeInt(tile.packedPosition());
|
||||
@@ -238,7 +247,7 @@ public class Puddle extends Entity implements SerializableEntity, Poolable{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Puddle add() {
|
||||
return add(puddleGroup);
|
||||
public EntityGroup targetGroup() {
|
||||
return puddleGroup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package io.anuke.mindustry.entities.effect;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import io.anuke.ucore.entities.TimedEntity;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.entities.impl.TimedEntity;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
@@ -16,7 +17,8 @@ public class Rubble extends TimedEntity implements BelowLiquidEffect{
|
||||
public static void create(float x, float y, int size){
|
||||
Rubble rubble = new Rubble();
|
||||
rubble.size = size;
|
||||
rubble.set(x, y).add();
|
||||
rubble.set(x, y);
|
||||
rubble.add();
|
||||
}
|
||||
|
||||
public Rubble(){
|
||||
@@ -38,7 +40,7 @@ public class Rubble extends TimedEntity implements BelowLiquidEffect{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rubble add() {
|
||||
return add(groundEffectGroup);
|
||||
public EntityGroup targetGroup() {
|
||||
return groundEffectGroup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
package io.anuke.mindustry.entities.effect;
|
||||
|
||||
import com.badlogic.gdx.math.Interpolation;
|
||||
import io.anuke.mindustry.entities.units.BaseUnit;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.types.defense.ShieldBlock;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.BulletEntity;
|
||||
import io.anuke.ucore.entities.Entities;
|
||||
import io.anuke.ucore.entities.Entity;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.entities.impl.BaseEntity;
|
||||
import io.anuke.ucore.graphics.Fill;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
import static io.anuke.mindustry.Vars.bulletGroup;
|
||||
import static io.anuke.mindustry.Vars.shieldGroup;
|
||||
|
||||
//todo re-implement
|
||||
public class Shield extends Entity{
|
||||
public class Shield extends BaseEntity {
|
||||
public boolean active;
|
||||
public boolean hitPlayers = false;
|
||||
public float radius = 0f;
|
||||
@@ -53,7 +50,8 @@ public class Shield extends Entity{
|
||||
}
|
||||
|
||||
ShieldBlock block = (ShieldBlock)tile.block();
|
||||
|
||||
|
||||
/*
|
||||
Entities.getNearby(bulletGroup, x, y, block.shieldRadius * 2*uptime + 10, entity->{
|
||||
BulletEntity bullet = (BulletEntity)entity;
|
||||
if((bullet.owner instanceof BaseUnit || hitPlayers)){
|
||||
@@ -64,7 +62,7 @@ public class Shield extends Entity{
|
||||
((ShieldBlock)tile.block()).handleBullet(tile, bullet);
|
||||
}
|
||||
}
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,12 +81,12 @@ public class Shield extends Entity{
|
||||
public void removeDelay(){
|
||||
active = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Shield add(){
|
||||
return super.add(shieldGroup);
|
||||
public EntityGroup targetGroup() {
|
||||
return shieldGroup;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void added(){
|
||||
active = true;
|
||||
|
||||
+12
-9
@@ -1,10 +1,12 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
package io.anuke.mindustry.entities.traits;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.utils.Queue;
|
||||
import io.anuke.mindustry.Vars;
|
||||
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.Unit;
|
||||
import io.anuke.mindustry.entities.effect.ItemTransfer;
|
||||
import io.anuke.mindustry.game.EventType.BlockBuildEvent;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
@@ -31,7 +33,7 @@ import java.util.Arrays;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
/**Interface for units that build, break or mine things.*/
|
||||
public interface BlockBuilder {
|
||||
public interface BuilderTrait {
|
||||
//these are not instance variables!
|
||||
Translator[] tmptr = {new Translator(), new Translator(), new Translator(), new Translator()};
|
||||
float placeDistance = 200f;
|
||||
@@ -109,7 +111,7 @@ public interface BlockBuilder {
|
||||
if(unit.distanceTo(tile) > placeDistance) { //out of range, skip it.
|
||||
getPlaceQueue().removeFirst();
|
||||
}else if(current.remove){
|
||||
if(Build.validBreak(unit.team, current.x, current.y) && current.recipe == Recipe.getByResult(tile.block())){ //if it's valid, break it
|
||||
if(Build.validBreak(unit.getTeam(), current.x, current.y) && current.recipe == Recipe.getByResult(tile.block())){ //if it's valid, break it
|
||||
|
||||
float progress = 1f / tile.getBreakTime();
|
||||
TileEntity core = unit.getClosestCore();
|
||||
@@ -133,7 +135,7 @@ public interface BlockBuilder {
|
||||
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(tile.drawx(), tile.drawy()), 0.4f);
|
||||
|
||||
if(current.progress >= 1f){
|
||||
Build.breakBlock(unit.team, current.x, current.y, true, true);
|
||||
Build.breakBlock(unit.getTeam(), current.x, current.y, true, true);
|
||||
}
|
||||
}else{
|
||||
//otherwise, skip it
|
||||
@@ -141,12 +143,12 @@ public interface BlockBuilder {
|
||||
}
|
||||
}else{
|
||||
if (!(tile.block() instanceof BuildBlock)) { //check if haven't started placing
|
||||
if(Build.validPlace(unit.team, current.x, current.y, current.recipe.result, current.rotation)){
|
||||
if(Build.validPlace(unit.getTeam(), current.x, current.y, current.recipe.result, current.rotation)){
|
||||
//if it's valid, place it
|
||||
Build.placeBlock(unit.team, current.x, current.y, current.recipe, current.rotation);
|
||||
Build.placeBlock(unit.getTeam(), current.x, current.y, current.recipe, current.rotation);
|
||||
|
||||
//fire place event.
|
||||
threads.run(() -> Events.fire(BlockBuildEvent.class, unit.team, world.tile(current.x, current.y)));
|
||||
threads.run(() -> Events.fire(BlockBuildEvent.class, unit.getTeam(), world.tile(current.x, current.y)));
|
||||
}else{
|
||||
//otherwise, skip it
|
||||
getPlaceQueue().removeFirst();
|
||||
@@ -270,8 +272,9 @@ public interface BlockBuilder {
|
||||
public final Recipe recipe;
|
||||
public final boolean remove;
|
||||
|
||||
float progress;
|
||||
float[] removeAccumulator;
|
||||
public float progress;
|
||||
|
||||
private float[] removeAccumulator;
|
||||
|
||||
/**This creates a build request.*/
|
||||
public BuildRequest(int x, int y, int rotation, Recipe recipe) {
|
||||
+4
-2
@@ -1,11 +1,13 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
package io.anuke.mindustry.entities.traits;
|
||||
|
||||
import io.anuke.ucore.entities.component.Entity;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**Marks an entity as serializable.*/
|
||||
public interface SerializableEntity {
|
||||
public interface SaveTrait extends Entity{
|
||||
void writeSave(DataOutputStream stream) throws IOException;
|
||||
void readSave(DataInputStream stream) throws IOException;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package io.anuke.mindustry.entities.traits;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import io.anuke.mindustry.net.Interpolator;
|
||||
import io.anuke.ucore.entities.component.Entity;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static io.anuke.mindustry.Vars.threads;
|
||||
|
||||
public interface SyncTrait extends Entity {
|
||||
|
||||
static boolean isSmoothing(){
|
||||
return threads.isEnabled() && threads.getFPS() <= Gdx.graphics.getFramesPerSecond() / 2f;
|
||||
}
|
||||
|
||||
default void setNet(float x, float y){
|
||||
set(x, y);
|
||||
getInterpolator().target.set(x, y);
|
||||
getInterpolator().last.set(x, y);
|
||||
getInterpolator().spacing = 1f;
|
||||
getInterpolator().time = 0f;
|
||||
}
|
||||
|
||||
default void interpolate(){
|
||||
getInterpolator().update();
|
||||
|
||||
setX(getInterpolator().pos.x);
|
||||
setY(getInterpolator().pos.y);
|
||||
}
|
||||
|
||||
Interpolator getInterpolator();
|
||||
|
||||
//Read and write sync data, usually position
|
||||
void write(ByteBuffer data);
|
||||
void read(ByteBuffer data, long time);
|
||||
}
|
||||
+3
-4
@@ -1,15 +1,14 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
package io.anuke.mindustry.entities.traits;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.ucore.entities.component.VelocityTrait;
|
||||
import io.anuke.ucore.util.Position;
|
||||
|
||||
/**Base interface for targetable entities.*/
|
||||
public interface Targetable extends Position{
|
||||
public interface TargetTrait extends Position, VelocityTrait {
|
||||
|
||||
boolean isDead();
|
||||
Team getTeam();
|
||||
Vector2 getVelocity();
|
||||
|
||||
/**Whether this entity is a valid target.*/
|
||||
default boolean isValid(){
|
||||
@@ -0,0 +1,8 @@
|
||||
package io.anuke.mindustry.entities.traits;
|
||||
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.ucore.entities.component.Entity;
|
||||
|
||||
public interface TeamTrait extends Entity {
|
||||
Team getTeam();
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package io.anuke.mindustry.entities.units;
|
||||
|
||||
import io.anuke.mindustry.content.fx.ExplosionFx;
|
||||
import io.anuke.mindustry.entities.Targetable;
|
||||
import io.anuke.mindustry.entities.traits.TargetTrait;
|
||||
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.bullet.BulletType;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.type.AmmoType;
|
||||
@@ -16,6 +15,7 @@ import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Effects.Effect;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
@@ -32,13 +32,13 @@ public abstract class BaseUnit extends Unit{
|
||||
private static int timerIndex = 0;
|
||||
|
||||
protected static final int timerTarget = timerIndex++;
|
||||
protected static final int timerBoost = timerIndex++;
|
||||
protected static final int timerReload = timerIndex++;
|
||||
|
||||
protected UnitType type;
|
||||
protected Timer timer = new Timer(5);
|
||||
protected StateMachine state = new StateMachine();
|
||||
protected Targetable target;
|
||||
protected boolean isWave;
|
||||
protected TargetTrait target;
|
||||
|
||||
public BaseUnit(UnitType type, Team team){
|
||||
this.type = type;
|
||||
@@ -48,6 +48,12 @@ public abstract class BaseUnit extends Unit{
|
||||
/**internal constructor used for deserialization, DO NOT USE*/
|
||||
public BaseUnit(){}
|
||||
|
||||
/**Sets this to a 'wave' unit, which means it has slightly different AI and will not run out of ammo.*/
|
||||
public void setWave(){
|
||||
isWave = true;
|
||||
inventory.setInfiniteAmmo(true);
|
||||
}
|
||||
|
||||
public void rotate(float angle){
|
||||
rotation = Mathf.slerpDelta(rotation, angle, type.rotatespeed);
|
||||
}
|
||||
@@ -79,7 +85,7 @@ public abstract class BaseUnit extends Unit{
|
||||
}
|
||||
|
||||
public void updateTargeting(){
|
||||
if(target == null || (target instanceof Unit && (target.isDead() || ((Unit)target).team == team))
|
||||
if(target == null || (target instanceof Unit && (target.isDead() || ((Unit)target).getTeam() == team))
|
||||
|| (target instanceof TileEntity && ((TileEntity) target).tile.entity == null)){
|
||||
target = null;
|
||||
}
|
||||
@@ -120,7 +126,7 @@ public abstract class BaseUnit extends Unit{
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMaxHealth() {
|
||||
public float maxHealth() {
|
||||
return type.health;
|
||||
}
|
||||
|
||||
@@ -144,12 +150,6 @@ public abstract class BaseUnit extends Unit{
|
||||
return 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(float x, float y){
|
||||
baseRotation = Mathf.slerpDelta(baseRotation, Mathf.atan2(x, y), type.baseRotateSpeed);
|
||||
super.move(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMass() {
|
||||
return type.mass;
|
||||
@@ -180,12 +180,14 @@ public abstract class BaseUnit extends Unit{
|
||||
|
||||
if(target != null) behavior();
|
||||
|
||||
x = Mathf.clamp(x, 0, world.width() * tilesize);
|
||||
y = Mathf.clamp(y, 0, world.height() * tilesize);
|
||||
if(!isWave) {
|
||||
x = Mathf.clamp(x, 0, world.width() * tilesize);
|
||||
y = Mathf.clamp(y, 0, world.height() * tilesize);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawSmooth(){
|
||||
public void draw(){
|
||||
|
||||
}
|
||||
|
||||
@@ -204,11 +206,6 @@ public abstract class BaseUnit extends Unit{
|
||||
return 14;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteShoot(BulletType type, float x, float y, float rotation, short data) {
|
||||
Bullet.create(type, this, x, y, rotation).damage = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeath(){
|
||||
super.onDeath();
|
||||
@@ -220,8 +217,8 @@ public abstract class BaseUnit extends Unit{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteDeath(){
|
||||
onDeath();
|
||||
public boolean collidesOthers() {
|
||||
return !isFlying();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -231,17 +228,16 @@ public abstract class BaseUnit extends Unit{
|
||||
|
||||
@Override
|
||||
public void added(){
|
||||
hitbox.solid = !isFlying();
|
||||
hitbox.setSize(type.hitsize);
|
||||
hitboxTile.setSize(type.hitsizeTile);
|
||||
state.set(getStartState());
|
||||
|
||||
heal();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BaseUnit add(){
|
||||
return add(unitGroups[team.ordinal()]);
|
||||
public EntityGroup targetGroup() {
|
||||
return unitGroups[team.ordinal()];
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -256,46 +252,16 @@ public abstract class BaseUnit extends Unit{
|
||||
byte type = stream.readByte();
|
||||
|
||||
this.type = UnitType.getByID(type);
|
||||
add(unitGroups[team.ordinal()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpawn(ByteBuffer buffer) {
|
||||
buffer.put(type.id);
|
||||
buffer.put((byte)team.ordinal());
|
||||
buffer.putFloat(x);
|
||||
buffer.putFloat(y);
|
||||
buffer.putShort((short)health);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSpawn(ByteBuffer buffer) {
|
||||
type = UnitType.getByID(buffer.get());
|
||||
team = Team.values()[buffer.get()];
|
||||
x = buffer.getFloat();
|
||||
y = buffer.getFloat();
|
||||
health = buffer.getShort();
|
||||
setNet(x, y);
|
||||
add();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuffer data) {
|
||||
data.putFloat(x);
|
||||
data.putFloat(y);
|
||||
data.putShort((short)(rotation *2));
|
||||
data.putShort((short)(baseRotation *2));
|
||||
data.putShort((short)health);
|
||||
//todo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuffer data, long time) {
|
||||
float x = data.getFloat();
|
||||
float y = data.getFloat();
|
||||
short rotation = data.getShort();
|
||||
short baserotation = data.getShort();
|
||||
short health = data.getShort();
|
||||
|
||||
interpolator.read(this.x, this.y, x, y, rotation/2f, baserotation/2f, time);
|
||||
this.health = health;
|
||||
//todo
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class FlyingUnit extends BaseUnit {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawSmooth() {
|
||||
public void draw() {
|
||||
Draw.alpha(hitTime / hitDuration);
|
||||
|
||||
Draw.rect(type.name, x, y, rotation - 90);
|
||||
@@ -52,7 +52,7 @@ public class FlyingUnit extends BaseUnit {
|
||||
|
||||
@Override
|
||||
public void behavior() {
|
||||
if(health <= health * type.retreatPercent &&
|
||||
if(health <= health * type.retreatPercent && !isWave &&
|
||||
Geometry.findClosest(x, y, world.indexer().getAllied(team, BlockFlag.repair)) != null){
|
||||
setState(retreat);
|
||||
}
|
||||
@@ -174,7 +174,7 @@ public class FlyingUnit extends BaseUnit {
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if(health >= getMaxHealth()){
|
||||
if(health >= maxHealth()){
|
||||
state.set(attack);
|
||||
}else if(!targetHasFlag(BlockFlag.repair)){
|
||||
retarget(() -> {
|
||||
|
||||
@@ -20,11 +20,28 @@ public abstract class GroundUnit extends BaseUnit {
|
||||
protected static float maxAim = 30f;
|
||||
|
||||
protected float walkTime;
|
||||
protected float baseRotation;
|
||||
|
||||
public GroundUnit(UnitType type, Team team) {
|
||||
super(type, team);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interpolate() {
|
||||
interpolator.update();
|
||||
|
||||
x = interpolator.pos.x;
|
||||
y = interpolator.pos.y;
|
||||
rotation = interpolator.values[0];
|
||||
baseRotation = interpolator.values[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(float x, float y){
|
||||
baseRotation = Mathf.slerpDelta(baseRotation, Mathf.atan2(x, y), type.baseRotateSpeed);
|
||||
super.move(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnitState getStartState() {
|
||||
return resupply;
|
||||
@@ -40,7 +57,7 @@ public abstract class GroundUnit extends BaseUnit {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawSmooth() {
|
||||
public void draw() {
|
||||
Draw.alpha(hitTime / hitDuration);
|
||||
|
||||
float walktime = walkTime;
|
||||
@@ -75,7 +92,7 @@ public abstract class GroundUnit extends BaseUnit {
|
||||
|
||||
@Override
|
||||
public void behavior() {
|
||||
if(health <= health * type.retreatPercent && !inventory.isInfiniteAmmo()){
|
||||
if(health <= health * type.retreatPercent && !isWave){
|
||||
setState(retreat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package io.anuke.mindustry.entities.units.types;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.utils.Queue;
|
||||
import io.anuke.mindustry.content.Items;
|
||||
import io.anuke.mindustry.entities.BlockBuilder;
|
||||
import io.anuke.mindustry.entities.traits.BuilderTrait;
|
||||
import io.anuke.mindustry.entities.TileEntity;
|
||||
import io.anuke.mindustry.entities.Units;
|
||||
import io.anuke.mindustry.entities.units.BaseUnit;
|
||||
@@ -29,7 +29,7 @@ import io.anuke.ucore.util.Mathf;
|
||||
import static io.anuke.mindustry.Vars.unitGroups;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class Drone extends FlyingUnit implements BlockBuilder{
|
||||
public class Drone extends FlyingUnit implements BuilderTrait {
|
||||
protected static float healSpeed = 0.1f;
|
||||
protected static float discoverRange = 120f;
|
||||
protected static boolean initialized;
|
||||
|
||||
@@ -31,7 +31,7 @@ public class Vtol extends FlyingUnit {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawSmooth() {
|
||||
public void draw() {
|
||||
Draw.alpha(hitTime / hitDuration);
|
||||
|
||||
Draw.rect(type.name, x, y, rotation - 90);
|
||||
|
||||
Reference in New Issue
Block a user