Splitting of building+mining into separate traits
This commit is contained in:
@@ -113,9 +113,11 @@ android{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes{
|
if(project.hasProperty("RELEASE_STORE_FILE")) {
|
||||||
release{
|
buildTypes {
|
||||||
signingConfig signingConfigs.release
|
release {
|
||||||
|
signingConfig signingConfigs.release
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ allprojects{
|
|||||||
maven{ url 'https://jitpack.io' }
|
maven{ url 'https://jitpack.io' }
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType(Javadoc).all{ enabled = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
project(":desktop"){
|
project(":desktop"){
|
||||||
@@ -175,7 +177,7 @@ project(":core"){
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
if(System.properties["user.name"] == "anuke"){
|
if(System.properties["user.name"] == "anuke" && !System.properties["os.name"].contains("Mac")){
|
||||||
task cleanGen{
|
task cleanGen{
|
||||||
doFirst{
|
doFirst{
|
||||||
delete{
|
delete{
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,26 +1,18 @@
|
|||||||
package io.anuke.mindustry.entities.traits;
|
package io.anuke.mindustry.entities.traits;
|
||||||
|
|
||||||
import io.anuke.arc.Core;
|
import io.anuke.arc.*;
|
||||||
import io.anuke.arc.Events;
|
import io.anuke.arc.collection.*;
|
||||||
import io.anuke.arc.collection.Array;
|
|
||||||
import io.anuke.arc.collection.Queue;
|
|
||||||
import io.anuke.arc.graphics.Color;
|
|
||||||
import io.anuke.arc.graphics.g2d.*;
|
import io.anuke.arc.graphics.g2d.*;
|
||||||
import io.anuke.arc.math.Angles;
|
import io.anuke.arc.math.*;
|
||||||
import io.anuke.arc.math.Mathf;
|
|
||||||
import io.anuke.arc.math.geom.Vector2;
|
import io.anuke.arc.math.geom.Vector2;
|
||||||
import io.anuke.arc.util.Time;
|
import io.anuke.arc.util.Time;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.content.Blocks;
|
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.entities.type.*;
|
||||||
import io.anuke.mindustry.game.EventType.BuildSelectEvent;
|
import io.anuke.mindustry.game.EventType.BuildSelectEvent;
|
||||||
import io.anuke.mindustry.gen.Call;
|
import io.anuke.mindustry.gen.Call;
|
||||||
import io.anuke.mindustry.graphics.Pal;
|
import io.anuke.mindustry.graphics.Pal;
|
||||||
import io.anuke.mindustry.graphics.Shapes;
|
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.type.Item;
|
|
||||||
import io.anuke.mindustry.world.*;
|
import io.anuke.mindustry.world.*;
|
||||||
import io.anuke.mindustry.world.blocks.BuildBlock;
|
import io.anuke.mindustry.world.blocks.BuildBlock;
|
||||||
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
|
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
|
||||||
@@ -29,21 +21,15 @@ import java.io.*;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
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.*;
|
||||||
import static io.anuke.mindustry.entities.traits.BuilderTrait.BuildDataStatic.tmptr;
|
|
||||||
|
|
||||||
/**
|
/** Interface for units that build things.*/
|
||||||
* Interface for units that build, break or mine things.
|
|
||||||
*/
|
|
||||||
public interface BuilderTrait extends Entity, TeamTrait{
|
public interface BuilderTrait extends Entity, TeamTrait{
|
||||||
//these are not instance variables!
|
//these are not instance variables!
|
||||||
float placeDistance = 220f;
|
float placeDistance = 220f;
|
||||||
float mineDistance = 70f;
|
float mineDistance = 70f;
|
||||||
|
|
||||||
/**
|
/** Updates building mechanism for this unit.*/
|
||||||
* Update building mechanism for this unit.
|
|
||||||
* This includes mining.
|
|
||||||
*/
|
|
||||||
default void updateBuilding(){
|
default void updateBuilding(){
|
||||||
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : placeDistance;
|
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : placeDistance;
|
||||||
Unit unit = (Unit)this;
|
Unit unit = (Unit)this;
|
||||||
@@ -65,14 +51,8 @@ public interface BuilderTrait extends Entity, TeamTrait{
|
|||||||
|
|
||||||
BuildRequest current = getCurrentRequest();
|
BuildRequest current = getCurrentRequest();
|
||||||
|
|
||||||
//update mining here
|
|
||||||
if(current == null){
|
if(current == null){
|
||||||
if(getMineTile() != null){
|
|
||||||
updateMining();
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}else{
|
|
||||||
setMineTile(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tile tile = world.tile(current.x, current.y);
|
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. */
|
/** Returns the queue for storing build requests. */
|
||||||
Queue<BuildRequest> getPlaceQueue();
|
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. */
|
/** Build power, can be any float. 1 = builds recipes in normal time, 0 = doesn't build at all. */
|
||||||
float getBuildPower(Tile tile);
|
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. */
|
/** Whether this type of builder can begin creating new blocks. */
|
||||||
default boolean canCreateBlocks(){
|
default boolean canCreateBlocks(){
|
||||||
return true;
|
return true;
|
||||||
@@ -236,60 +204,18 @@ public interface BuilderTrait extends Entity, TeamTrait{
|
|||||||
return getPlaceQueue().size == 0 ? null : getPlaceQueue().first();
|
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{
|
class BuildDataStatic{
|
||||||
static Array<BuildRequest> removal = new Array<>();
|
static Array<BuildRequest> removal = new Array<>();
|
||||||
static Vector2[] tmptr = new Vector2[]{new Vector2(), new Vector2(), new Vector2(), new Vector2()};
|
static Vector2[] tmptr = new Vector2[]{new Vector2(), new Vector2(), new Vector2(), new Vector2()};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Do not call directly. */
|
/** Draw placement effects for an entity. */
|
||||||
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 */
|
|
||||||
default void drawBuilding(){
|
default void drawBuilding(){
|
||||||
|
if(!isBuilding()) return;
|
||||||
|
|
||||||
Unit unit = (Unit)this;
|
Unit unit = (Unit)this;
|
||||||
BuildRequest request;
|
BuildRequest request = getCurrentRequest();
|
||||||
if(!isBuilding()){
|
|
||||||
if(getMineTile() != null){
|
|
||||||
drawMining();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
request = getCurrentRequest();
|
|
||||||
|
|
||||||
Tile tile = world.tile(request.x, request.y);
|
Tile tile = world.tile(request.x, request.y);
|
||||||
|
|
||||||
if(dst(tile) > placeDistance && !state.isEditor()){
|
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);
|
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),
|
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,
|
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);
|
Draw.alpha(1f);
|
||||||
|
|
||||||
@@ -325,35 +251,6 @@ public interface BuilderTrait extends Entity, TeamTrait{
|
|||||||
Draw.color();
|
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 for storing build requests. Can be either a place or remove request. */
|
||||||
class BuildRequest{
|
class BuildRequest{
|
||||||
public final int x, y, rotation;
|
public final int x, y, rotation;
|
||||||
|
|||||||
101
core/src/io/anuke/mindustry/entities/traits/MinerTrait.java
Normal file
101
core/src/io/anuke/mindustry/entities/traits/MinerTrait.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ import java.io.*;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
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 timerSync = 2;
|
||||||
public static final int timerAbility = 3;
|
public static final int timerAbility = 3;
|
||||||
private static final int timerShootLeft = 0;
|
private static final int timerShootLeft = 0;
|
||||||
@@ -362,7 +362,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
|||||||
public void drawOver(){
|
public void drawOver(){
|
||||||
if(dead) return;
|
if(dead) return;
|
||||||
|
|
||||||
drawBuilding();
|
drawMechanics();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -551,7 +551,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
|||||||
|
|
||||||
if(!isLocal){
|
if(!isLocal){
|
||||||
interpolate();
|
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
|
status.update(this); //status effect updating also happens with non locals for effect purposes
|
||||||
updateVelocityStatus(); //velocity too, for visual purposes
|
updateVelocityStatus(); //velocity too, for visual purposes
|
||||||
|
|
||||||
@@ -572,7 +572,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
|||||||
|
|
||||||
isTyping = ui.chatfrag.chatOpen();
|
isTyping = ui.chatfrag.chatOpen();
|
||||||
|
|
||||||
updateBuilding();
|
updateMechanics();
|
||||||
|
|
||||||
if(!mech.flying){
|
if(!mech.flying){
|
||||||
clampPosition();
|
clampPosition();
|
||||||
|
|||||||
217
core/src/io/anuke/mindustry/entities/type/base/MinerDrone.java
Normal file
217
core/src/io/anuke/mindustry/entities/type/base/MinerDrone.java
Normal 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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
package io.anuke.mindustry.entities.type.base;
|
package io.anuke.mindustry.entities.type.base;
|
||||||
|
|
||||||
public class Phantom extends Drone{
|
public class Phantom extends UtilityDrone{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package io.anuke.mindustry.entities.type.base;
|
package io.anuke.mindustry.entities.type.base;
|
||||||
|
|
||||||
public class Spirit extends Drone{
|
public class Spirit extends UtilityDrone{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,11 @@ import io.anuke.arc.Events;
|
|||||||
import io.anuke.arc.collection.Queue;
|
import io.anuke.arc.collection.Queue;
|
||||||
import io.anuke.arc.math.Mathf;
|
import io.anuke.arc.math.Mathf;
|
||||||
import io.anuke.arc.math.geom.Geometry;
|
import io.anuke.arc.math.geom.Geometry;
|
||||||
import io.anuke.arc.util.Structs;
|
import io.anuke.mindustry.entities.*;
|
||||||
import io.anuke.mindustry.content.Blocks;
|
|
||||||
import io.anuke.mindustry.entities.EntityGroup;
|
|
||||||
import io.anuke.mindustry.entities.Units;
|
|
||||||
import io.anuke.mindustry.entities.traits.BuilderTrait;
|
import io.anuke.mindustry.entities.traits.BuilderTrait;
|
||||||
import io.anuke.mindustry.entities.type.*;
|
import io.anuke.mindustry.entities.type.*;
|
||||||
import io.anuke.mindustry.entities.units.UnitState;
|
import io.anuke.mindustry.entities.units.UnitState;
|
||||||
import io.anuke.mindustry.game.EventType.BuildSelectEvent;
|
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.Tile;
|
||||||
import io.anuke.mindustry.world.blocks.BuildBlock;
|
import io.anuke.mindustry.world.blocks.BuildBlock;
|
||||||
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
|
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
|
||||||
@@ -24,9 +18,8 @@ import java.io.*;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class Drone extends FlyingUnit implements BuilderTrait{
|
/** A drone that only builds and/or repairs.*/
|
||||||
protected Item targetItem;
|
public class UtilityDrone extends FlyingUnit implements BuilderTrait{
|
||||||
protected Tile mineTile;
|
|
||||||
protected Queue<BuildRequest> placeQueue = new Queue<>();
|
protected Queue<BuildRequest> placeQueue = new Queue<>();
|
||||||
protected boolean isBreaking;
|
protected boolean isBreaking;
|
||||||
|
|
||||||
@@ -34,6 +27,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
|||||||
|
|
||||||
build = new UnitState(){
|
build = new UnitState(){
|
||||||
|
|
||||||
|
//TODO follow players
|
||||||
public void entered(){
|
public void entered(){
|
||||||
if(!(target instanceof BuildEntity)){
|
if(!(target instanceof BuildEntity)){
|
||||||
target = null;
|
target = null;
|
||||||
@@ -78,12 +72,13 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
|||||||
retarget(() -> target = Units.findDamagedTile(team, x, y));
|
retarget(() -> target = Units.findDamagedTile(team, x, y));
|
||||||
|
|
||||||
if(target != null){
|
if(target != null){
|
||||||
if(target.dst(Drone.this) > type.range){
|
if(target.dst(UtilityDrone.this) > type.range){
|
||||||
circle(type.range * 0.9f);
|
circle(type.range * 0.9f);
|
||||||
}else{
|
}else{
|
||||||
getWeapon().update(Drone.this, target.getX(), target.getY());
|
getWeapon().update(UtilityDrone.this, target.getX(), target.getY());
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
//circle spawner if there's nothing to repair
|
||||||
if(getSpawner() != null){
|
if(getSpawner() != null){
|
||||||
target = getSpawner();
|
target = getSpawner();
|
||||||
circle(type.range * 0.9f);
|
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(){
|
retreat = new UnitState(){
|
||||||
public void entered(){
|
public void entered(){
|
||||||
target = null;
|
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));
|
Tile repairPoint = Geometry.findClosest(x, y, world.indexer.getAllied(team, BlockFlag.repair));
|
||||||
if(repairPoint != null){
|
if(repairPoint != null){
|
||||||
target = repairPoint;
|
target = repairPoint;
|
||||||
}else if(getSpawner() != null){
|
}else{
|
||||||
target = getSpawner();
|
setState(repair);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
@@ -215,8 +117,8 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
|||||||
if(!(event.tile.entity instanceof BuildEntity)) return;
|
if(!(event.tile.entity instanceof BuildEntity)) return;
|
||||||
|
|
||||||
for(BaseUnit unit : group.all()){
|
for(BaseUnit unit : group.all()){
|
||||||
if(unit instanceof Drone){
|
if(unit instanceof UtilityDrone){
|
||||||
Drone drone = (Drone)unit;
|
UtilityDrone drone = (UtilityDrone)unit;
|
||||||
if(drone.isBuilding()){
|
if(drone.isBuilding()){
|
||||||
//stop building if opposite building begins.
|
//stop building if opposite building begins.
|
||||||
BuildRequest req = drone.getCurrentRequest();
|
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
|
@Override
|
||||||
public float getBuildPower(Tile tile){
|
public float getBuildPower(Tile tile){
|
||||||
return type.buildPower;
|
return type.buildPower;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getMinePower(){
|
|
||||||
return type.minePower;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Queue<BuildRequest> getPlaceQueue(){
|
public Queue<BuildRequest> getPlaceQueue(){
|
||||||
return placeQueue;
|
return placeQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Tile getMineTile(){
|
|
||||||
return mineTile;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMineTile(Tile tile){
|
|
||||||
mineTile = tile;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
super.update();
|
super.update();
|
||||||
@@ -292,7 +174,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateRotation(){
|
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);
|
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.3f);
|
||||||
}else{
|
}else{
|
||||||
rotation = Mathf.slerpDelta(rotation, velocity.angle(), 0.3f);
|
rotation = Mathf.slerpDelta(rotation, velocity.angle(), 0.3f);
|
||||||
@@ -321,14 +203,6 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
|||||||
return isBuilding() ? placeDistance * 2f : 30f;
|
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
|
@Override
|
||||||
public boolean canCreateBlocks(){
|
public boolean canCreateBlocks(){
|
||||||
return true;
|
return true;
|
||||||
@@ -337,7 +211,6 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
|||||||
@Override
|
@Override
|
||||||
public void write(DataOutput data) throws IOException{
|
public void write(DataOutput data) throws IOException{
|
||||||
super.write(data);
|
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);
|
data.writeInt(state.is(repair) && target instanceof TileEntity ? ((TileEntity)target).tile.pos() : -1);
|
||||||
writeBuilding(data);
|
writeBuilding(data);
|
||||||
}
|
}
|
||||||
@@ -345,15 +218,10 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
|||||||
@Override
|
@Override
|
||||||
public void read(DataInput data) throws IOException{
|
public void read(DataInput data) throws IOException{
|
||||||
super.read(data);
|
super.read(data);
|
||||||
int mined = data.readInt();
|
|
||||||
int repairing = data.readInt();
|
int repairing = data.readInt();
|
||||||
|
|
||||||
readBuilding(data);
|
readBuilding(data);
|
||||||
|
|
||||||
if(mined != -1){
|
|
||||||
mineTile = world.tile(mined);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(repairing != -1){
|
if(repairing != -1){
|
||||||
Tile tile = world.tile(repairing);
|
Tile tile = world.tile(repairing);
|
||||||
target = tile.entity;
|
target = tile.entity;
|
||||||
Reference in New Issue
Block a user