Splitting of building+mining into separate traits

This commit is contained in:
Anuken 2019-06-12 14:03:50 -04:00
parent dc3c27297f
commit 0aee75c1c1
10 changed files with 379 additions and 270 deletions

View File

@ -113,9 +113,11 @@ android{
}
}
buildTypes{
release{
signingConfig signingConfigs.release
if(project.hasProperty("RELEASE_STORE_FILE")) {
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
}

View File

@ -113,6 +113,8 @@ allprojects{
maven{ url 'https://jitpack.io' }
jcenter()
}
tasks.withType(Javadoc).all{ enabled = false }
}
project(":desktop"){
@ -175,7 +177,7 @@ project(":core"){
}
dependencies{
if(System.properties["user.name"] == "anuke"){
if(System.properties["user.name"] == "anuke" && !System.properties["os.name"].contains("Mac")){
task cleanGen{
doFirst{
delete{

View File

@ -0,0 +1,22 @@
package io.anuke.mindustry.entities.traits;
/** A class for gracefully merging mining and building traits.*/
public interface BuilderMinerTrait extends MinerTrait, BuilderTrait{
default void updateMechanics(){
updateBuilding();
//mine only when not building
if(getCurrentRequest() == null){
updateMining();
}
}
default void drawMechanics(){
if(isBuilding()){
drawBuilding();
}else{
drawMining();
}
}
}

View File

@ -1,26 +1,18 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.arc.Core;
import io.anuke.arc.Events;
import io.anuke.arc.collection.Array;
import io.anuke.arc.collection.Queue;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.*;
import io.anuke.arc.collection.*;
import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.*;
import io.anuke.arc.math.geom.Vector2;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.entities.Effects;
import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.EventType.BuildSelectEvent;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.graphics.Shapes;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.blocks.BuildBlock;
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
@ -29,21 +21,15 @@ import java.io.*;
import java.util.Arrays;
import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.entities.traits.BuilderTrait.BuildDataStatic.removal;
import static io.anuke.mindustry.entities.traits.BuilderTrait.BuildDataStatic.tmptr;
import static io.anuke.mindustry.entities.traits.BuilderTrait.BuildDataStatic.*;
/**
* Interface for units that build, break or mine things.
*/
/** Interface for units that build things.*/
public interface BuilderTrait extends Entity, TeamTrait{
//these are not instance variables!
float placeDistance = 220f;
float mineDistance = 70f;
/**
* Update building mechanism for this unit.
* This includes mining.
*/
/** Updates building mechanism for this unit.*/
default void updateBuilding(){
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : placeDistance;
Unit unit = (Unit)this;
@ -65,14 +51,8 @@ public interface BuilderTrait extends Entity, TeamTrait{
BuildRequest current = getCurrentRequest();
//update mining here
if(current == null){
if(getMineTile() != null){
updateMining();
}
return;
}else{
setMineTile(null);
}
Tile tile = world.tile(current.x, current.y);
@ -137,21 +117,9 @@ public interface BuilderTrait extends Entity, TeamTrait{
/** Returns the queue for storing build requests. */
Queue<BuildRequest> getPlaceQueue();
/** Returns the tile this builder is currently mining. */
Tile getMineTile();
/** Sets the tile this builder is currently mining. */
void setMineTile(Tile tile);
/** Returns the minining speed of this miner. 1 = standard, 0.5 = half speed, 2 = double speed, etc. */
float getMinePower();
/** Build power, can be any float. 1 = builds recipes in normal time, 0 = doesn't build at all. */
float getBuildPower(Tile tile);
/** Returns whether or not this builder can mine a specific item type. */
boolean canMine(Item item);
/** Whether this type of builder can begin creating new blocks. */
default boolean canCreateBlocks(){
return true;
@ -236,60 +204,18 @@ public interface BuilderTrait extends Entity, TeamTrait{
return getPlaceQueue().size == 0 ? null : getPlaceQueue().first();
}
//due to iOS wierdness, this is apparently required
//due to iOS weirdness, this is apparently required
class BuildDataStatic{
static Array<BuildRequest> removal = new Array<>();
static Vector2[] tmptr = new Vector2[]{new Vector2(), new Vector2(), new Vector2(), new Vector2()};
}
/** Do not call directly. */
default void updateMining(){
Unit unit = (Unit)this;
Tile tile = getMineTile();
TileEntity core = unit.getClosestCore();
if(core == null || tile.block() != Blocks.air || dst(tile.worldx(), tile.worldy()) > mineDistance
|| tile.drop() == null || !unit.acceptsItem(tile.drop()) || !canMine(tile.drop())){
setMineTile(null);
}else{
Item item = tile.drop();
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(tile.worldx(), tile.worldy()), 0.4f);
if(Mathf.chance(Time.delta() * (0.06 - item.hardness * 0.01) * getMinePower())){
if(unit.dst(core) < mineTransferRange && core.tile.block().acceptStack(item, 1, core.tile, unit) == 1){
Call.transferItemTo(item, 1,
tile.worldx() + Mathf.range(tilesize / 2f),
tile.worldy() + Mathf.range(tilesize / 2f), core.tile);
}else if(unit.acceptsItem(item)){
Call.transferItemToUnit(item,
tile.worldx() + Mathf.range(tilesize / 2f),
tile.worldy() + Mathf.range(tilesize / 2f),
unit);
}
}
if(Mathf.chance(0.06 * Time.delta())){
Effects.effect(Fx.pulverizeSmall,
tile.worldx() + Mathf.range(tilesize / 2f),
tile.worldy() + Mathf.range(tilesize / 2f), 0f, item.color);
}
}
}
/** Draw placement effects for an entity. This includes mining */
/** Draw placement effects for an entity. */
default void drawBuilding(){
if(!isBuilding()) return;
Unit unit = (Unit)this;
BuildRequest request;
if(!isBuilding()){
if(getMineTile() != null){
drawMining();
}
return;
}
request = getCurrentRequest();
BuildRequest request = getCurrentRequest();
Tile tile = world.tile(request.x, request.y);
if(dst(tile) > placeDistance && !state.isEditor()){
@ -310,10 +236,10 @@ public interface BuilderTrait extends Entity, TeamTrait{
tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz);
Arrays.sort(tmptr, (a, b) -> -Float.compare(Angles.angleDist(Angles.angle(unit.x, unit.y, a.x, a.y), ang),
Angles.angleDist(Angles.angle(unit.x, unit.y, b.x, b.y), ang)));
Angles.angleDist(Angles.angle(unit.x, unit.y, b.x, b.y), ang)));
float x1 = tmptr[0].x, y1 = tmptr[0].y,
x3 = tmptr[1].x, y3 = tmptr[1].y;
x3 = tmptr[1].x, y3 = tmptr[1].y;
Draw.alpha(1f);
@ -325,35 +251,6 @@ public interface BuilderTrait extends Entity, TeamTrait{
Draw.color();
}
/** Internal use only. */
default void drawMining(){
Unit unit = (Unit)this;
Tile tile = getMineTile();
if(tile == null) return;
float focusLen = 4f + Mathf.absin(Time.time(), 1.1f, 0.5f);
float swingScl = 12f, swingMag = tilesize / 8f;
float flashScl = 0.3f;
float px = unit.x + Angles.trnsx(unit.rotation, focusLen);
float py = unit.y + Angles.trnsy(unit.rotation, focusLen);
float ex = tile.worldx() + Mathf.sin(Time.time() + 48, swingScl, swingMag);
float ey = tile.worldy() + Mathf.sin(Time.time() + 48, swingScl + 2f, swingMag);
Draw.color(Color.LIGHT_GRAY, Color.WHITE, 1f - flashScl + Mathf.absin(Time.time(), 0.5f, flashScl));
Shapes.laser("minelaser", "minelaser-end", px, py, ex, ey, 0.75f);
if(unit instanceof Player && ((Player)unit).isLocal){
Lines.stroke(1f, Pal.accent);
Lines.poly(tile.worldx(), tile.worldy(), 4, tilesize / 2f * Mathf.sqrt2, Time.time());
}
Draw.color();
}
/** Class for storing build requests. Can be either a place or remove request. */
class BuildRequest{
public final int x, y, rotation;

View File

@ -0,0 +1,101 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.math.*;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.content.*;
import io.anuke.mindustry.entities.Effects;
import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Tile;
import static io.anuke.mindustry.Vars.*;
public interface MinerTrait extends Entity{
/** Returns the range at which this miner can mine blocks.*/
default float getMiningRange(){
return 70f;
}
default boolean isMining(){
return getMineTile() != null;
}
/** Returns the tile this builder is currently mining. */
Tile getMineTile();
/** Sets the tile this builder is currently mining. */
void setMineTile(Tile tile);
/** Returns the mining speed of this miner. 1 = standard, 0.5 = half speed, 2 = double speed, etc. */
float getMinePower();
/** Returns whether or not this builder can mine a specific item type. */
boolean canMine(Item item);
default void updateMining(){
Unit unit = (Unit)this;
Tile tile = getMineTile();
TileEntity core = unit.getClosestCore();
if(tile == null || core == null || tile.block() != Blocks.air || dst(tile.worldx(), tile.worldy()) > getMiningRange()
|| tile.drop() == null || !unit.acceptsItem(tile.drop()) || !canMine(tile.drop())){
setMineTile(null);
}else{
Item item = tile.drop();
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(tile.worldx(), tile.worldy()), 0.4f);
if(Mathf.chance(Time.delta() * (0.06 - item.hardness * 0.01) * getMinePower())){
if(unit.dst(core) < mineTransferRange && core.tile.block().acceptStack(item, 1, core.tile, unit) == 1){
Call.transferItemTo(item, 1,
tile.worldx() + Mathf.range(tilesize / 2f),
tile.worldy() + Mathf.range(tilesize / 2f), core.tile);
}else if(unit.acceptsItem(item)){
Call.transferItemToUnit(item,
tile.worldx() + Mathf.range(tilesize / 2f),
tile.worldy() + Mathf.range(tilesize / 2f),
unit);
}
}
if(Mathf.chance(0.06 * Time.delta())){
Effects.effect(Fx.pulverizeSmall,
tile.worldx() + Mathf.range(tilesize / 2f),
tile.worldy() + Mathf.range(tilesize / 2f), 0f, item.color);
}
}
}
default void drawMining(){
Unit unit = (Unit)this;
Tile tile = getMineTile();
if(tile == null) return;
float focusLen = 4f + Mathf.absin(Time.time(), 1.1f, 0.5f);
float swingScl = 12f, swingMag = tilesize / 8f;
float flashScl = 0.3f;
float px = unit.x + Angles.trnsx(unit.rotation, focusLen);
float py = unit.y + Angles.trnsy(unit.rotation, focusLen);
float ex = tile.worldx() + Mathf.sin(Time.time() + 48, swingScl, swingMag);
float ey = tile.worldy() + Mathf.sin(Time.time() + 48, swingScl + 2f, swingMag);
Draw.color(Color.LIGHT_GRAY, Color.WHITE, 1f - flashScl + Mathf.absin(Time.time(), 0.5f, flashScl));
Shapes.laser("minelaser", "minelaser-end", px, py, ex, ey, 0.75f);
if(unit instanceof Player && ((Player)unit).isLocal){
Lines.stroke(1f, Pal.accent);
Lines.poly(tile.worldx(), tile.worldy(), 4, tilesize / 2f * Mathf.sqrt2, Time.time());
}
Draw.color();
}
}

View File

@ -33,7 +33,7 @@ import java.io.*;
import static io.anuke.mindustry.Vars.*;
public class Player extends Unit implements BuilderTrait, ShooterTrait{
public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
public static final int timerSync = 2;
public static final int timerAbility = 3;
private static final int timerShootLeft = 0;
@ -362,7 +362,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
public void drawOver(){
if(dead) return;
drawBuilding();
drawMechanics();
}
@Override
@ -551,7 +551,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
if(!isLocal){
interpolate();
updateBuilding(); //building happens even with non-locals
updateMechanics(); //building happens even with non-locals
status.update(this); //status effect updating also happens with non locals for effect purposes
updateVelocityStatus(); //velocity too, for visual purposes
@ -572,7 +572,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
isTyping = ui.chatfrag.chatOpen();
updateBuilding();
updateMechanics();
if(!mech.flying){
clampPosition();

View File

@ -0,0 +1,217 @@
package io.anuke.mindustry.entities.type.base;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.util.Structs;
import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.entities.traits.MinerTrait;
import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.entities.units.UnitState;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.meta.BlockFlag;
import java.io.*;
import static io.anuke.mindustry.Vars.world;
/** A drone that only mines.*/
public class MinerDrone extends FlyingUnit implements MinerTrait{
protected Item targetItem;
protected Tile mineTile;
public final UnitState
mine = new UnitState(){
public void entered(){
target = null;
}
public void update(){
TileEntity entity = getClosestCore();
if(entity == null) return;
if(targetItem == null){
findItem();
}
//core full
if(targetItem != null && entity.block.acceptStack(targetItem, 1, entity.tile, MinerDrone.this) == 0){
MinerDrone.this.clearItem();
return;
}
//if inventory is full, drop it off.
if(item.amount >= getItemCapacity()){
setState(drop);
}else{
if(targetItem != null && !acceptsItem(targetItem)){
setState(drop);
return;
}
retarget(() -> {
if(getMineTile() == null){
findItem();
}
if(targetItem == null) return;
target = world.indexer.findClosestOre(x, y, targetItem);
});
if(target instanceof Tile){
moveTo(type.range / 1.5f);
if(dst(target) < type.range && mineTile != target){
setMineTile((Tile)target);
}
if(((Tile)target).block() != Blocks.air){
setState(drop);
}
}else{
//nothing to mine anymore, core full: circle spawnpoint
if(getSpawner() != null){
target = getSpawner();
circle(40f);
}
}
}
}
public void exited(){
setMineTile(null);
}
},
drop = new UnitState(){
public void entered(){
target = null;
}
public void update(){
if(item.amount == 0){
setState(mine);
return;
}
if(item.item.type != ItemType.material){
item.amount = 0;
setState(mine);
return;
}
target = getClosestCore();
if(target == null) return;
TileEntity tile = (TileEntity)target;
if(dst(target) < type.range){
if(tile.tile.block().acceptStack(item.item, item.amount, tile.tile, MinerDrone.this) == item.amount){
Call.transferItemTo(item.item, item.amount, x, y, tile.tile);
item.amount = 0;
}
setState(mine);
}
circle(type.range / 1.8f);
}
},
retreat = new UnitState(){
public void entered(){
target = null;
}
public void update(){
if(health >= maxHealth()){
state.set(attack);
}else if(!targetHasFlag(BlockFlag.repair)){
retarget(() -> {
Tile repairPoint = Geometry.findClosest(x, y, world.indexer.getAllied(team, BlockFlag.repair));
if(repairPoint != null){
target = repairPoint;
}else{
setState(mine);
}
});
}else{
circle(40f);
}
}
};
@Override
public void update(){
super.update();
updateMining();
}
@Override
protected void updateRotation(){
if(target != null && state.is(mine)){
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.3f);
}else{
rotation = Mathf.slerpDelta(rotation, velocity.angle(), 0.3f);
}
}
@Override
public void behavior(){
if(health <= health * type.retreatPercent){
setState(retreat);
}
}
@Override
public void drawOver(){
drawMining();
}
@Override
public boolean canMine(Item item){
return type.toMine.contains(item);
}
@Override
public float getMinePower(){
return type.minePower;
}
@Override
public Tile getMineTile(){
return mineTile;
}
@Override
public void setMineTile(Tile tile){
mineTile = tile;
}
@Override
public void write(DataOutput data) throws IOException{
super.write(data);
data.writeInt(mineTile == null || !state.is(mine) ? Pos.invalid : mineTile.pos());
}
@Override
public void read(DataInput data) throws IOException{
super.read(data);
mineTile = world.tile(data.readInt());
}
protected void findItem(){
TileEntity entity = getClosestCore();
if(entity == null){
return;
}
targetItem = Structs.findMin(type.toMine, world.indexer::hasOre, (a, b) -> -Integer.compare(entity.items.get(a), entity.items.get(b)));
}
}

View File

@ -1,5 +1,5 @@
package io.anuke.mindustry.entities.type.base;
public class Phantom extends Drone{
public class Phantom extends UtilityDrone{
}

View File

@ -1,4 +1,4 @@
package io.anuke.mindustry.entities.type.base;
public class Spirit extends Drone{
public class Spirit extends UtilityDrone{
}

View File

@ -4,17 +4,11 @@ import io.anuke.arc.Events;
import io.anuke.arc.collection.Queue;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.geom.Geometry;
import io.anuke.arc.util.Structs;
import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.entities.EntityGroup;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.traits.BuilderTrait;
import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.entities.units.UnitState;
import io.anuke.mindustry.game.EventType.BuildSelectEvent;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.ItemType;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.BuildBlock;
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
@ -24,9 +18,8 @@ import java.io.*;
import static io.anuke.mindustry.Vars.*;
public class Drone extends FlyingUnit implements BuilderTrait{
protected Item targetItem;
protected Tile mineTile;
/** A drone that only builds and/or repairs.*/
public class UtilityDrone extends FlyingUnit implements BuilderTrait{
protected Queue<BuildRequest> placeQueue = new Queue<>();
protected boolean isBreaking;
@ -34,6 +27,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
build = new UnitState(){
//TODO follow players
public void entered(){
if(!(target instanceof BuildEntity)){
target = null;
@ -78,12 +72,13 @@ public class Drone extends FlyingUnit implements BuilderTrait{
retarget(() -> target = Units.findDamagedTile(team, x, y));
if(target != null){
if(target.dst(Drone.this) > type.range){
if(target.dst(UtilityDrone.this) > type.range){
circle(type.range * 0.9f);
}else{
getWeapon().update(Drone.this, target.getX(), target.getY());
getWeapon().update(UtilityDrone.this, target.getX(), target.getY());
}
}else{
//circle spawner if there's nothing to repair
if(getSpawner() != null){
target = getSpawner();
circle(type.range * 0.9f);
@ -91,99 +86,6 @@ public class Drone extends FlyingUnit implements BuilderTrait{
}
}
},
mine = new UnitState(){
public void entered(){
target = null;
}
public void update(){
TileEntity entity = getClosestCore();
if(entity == null) return;
if(targetItem == null){
findItem();
}
//core full
if(targetItem != null && entity.block.acceptStack(targetItem, 1, entity.tile, Drone.this) == 0){
setState(repair);
return;
}
//if inventory is full, drop it off.
if(item.amount >= getItemCapacity()){
setState(drop);
}else{
if(targetItem != null && !acceptsItem(targetItem)){
setState(drop);
return;
}
retarget(() -> {
if(getMineTile() == null){
findItem();
}
if(targetItem == null) return;
target = world.indexer.findClosestOre(x, y, targetItem);
});
if(target instanceof Tile){
moveTo(type.range / 1.5f);
if(dst(target) < type.range && mineTile != target){
setMineTile((Tile)target);
}
if(((Tile)target).block() != Blocks.air){
setState(drop);
}
}
}
}
public void exited(){
setMineTile(null);
}
},
drop = new UnitState(){
public void entered(){
target = null;
}
public void update(){
if(item.amount == 0){
setState(mine);
return;
}
if(item.item.type != ItemType.material){
item.amount = 0;
setState(mine);
return;
}
target = getClosestCore();
if(target == null) return;
TileEntity tile = (TileEntity)target;
if(dst(target) < type.range){
if(tile.tile.block().acceptStack(item.item, item.amount, tile.tile, Drone.this) == item.amount){
Call.transferItemTo(item.item, item.amount, x, y, tile.tile);
item.amount = 0;
}
setState(repair);
}
circle(type.range / 1.8f);
}
},
retreat = new UnitState(){
public void entered(){
target = null;
@ -197,8 +99,8 @@ public class Drone extends FlyingUnit implements BuilderTrait{
Tile repairPoint = Geometry.findClosest(x, y, world.indexer.getAllied(team, BlockFlag.repair));
if(repairPoint != null){
target = repairPoint;
}else if(getSpawner() != null){
target = getSpawner();
}else{
setState(repair);
}
});
}else{
@ -215,8 +117,8 @@ public class Drone extends FlyingUnit implements BuilderTrait{
if(!(event.tile.entity instanceof BuildEntity)) return;
for(BaseUnit unit : group.all()){
if(unit instanceof Drone){
Drone drone = (Drone)unit;
if(unit instanceof UtilityDrone){
UtilityDrone drone = (UtilityDrone)unit;
if(drone.isBuilding()){
//stop building if opposite building begins.
BuildRequest req = drone.getCurrentRequest();
@ -230,36 +132,16 @@ public class Drone extends FlyingUnit implements BuilderTrait{
});
}
@Override
public boolean canMine(Item item){
return type.toMine.contains(item);
}
@Override
public float getBuildPower(Tile tile){
return type.buildPower;
}
@Override
public float getMinePower(){
return type.minePower;
}
@Override
public Queue<BuildRequest> getPlaceQueue(){
return placeQueue;
}
@Override
public Tile getMineTile(){
return mineTile;
}
@Override
public void setMineTile(Tile tile){
mineTile = tile;
}
@Override
public void update(){
super.update();
@ -292,7 +174,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
@Override
protected void updateRotation(){
if(target != null && ((state.is(repair) && target.dst(this) < type.range) || state.is(mine))){
if(target != null && state.is(repair) && target.dst(this) < type.range){
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.3f);
}else{
rotation = Mathf.slerpDelta(rotation, velocity.angle(), 0.3f);
@ -321,14 +203,6 @@ public class Drone extends FlyingUnit implements BuilderTrait{
return isBuilding() ? placeDistance * 2f : 30f;
}
protected void findItem(){
TileEntity entity = getClosestCore();
if(entity == null){
return;
}
targetItem = Structs.findMin(type.toMine, world.indexer::hasOre, (a, b) -> -Integer.compare(entity.items.get(a), entity.items.get(b)));
}
@Override
public boolean canCreateBlocks(){
return true;
@ -337,7 +211,6 @@ public class Drone extends FlyingUnit implements BuilderTrait{
@Override
public void write(DataOutput data) throws IOException{
super.write(data);
data.writeInt(mineTile == null || !state.is(mine) ? -1 : mineTile.pos());
data.writeInt(state.is(repair) && target instanceof TileEntity ? ((TileEntity)target).tile.pos() : -1);
writeBuilding(data);
}
@ -345,15 +218,10 @@ public class Drone extends FlyingUnit implements BuilderTrait{
@Override
public void read(DataInput data) throws IOException{
super.read(data);
int mined = data.readInt();
int repairing = data.readInt();
readBuilding(data);
if(mined != -1){
mineTile = world.tile(mined);
}
if(repairing != -1){
Tile tile = world.tile(repairing);
target = tile.entity;