Added core miner drone, massive amount of balancing/setup
This commit is contained in:
@@ -2,6 +2,7 @@ package io.anuke.mindustry.entities;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Pools;
|
||||
import com.badlogic.gdx.utils.Queue;
|
||||
@@ -87,6 +88,12 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
|
||||
|
||||
//region unit and event overrides, utility methods
|
||||
|
||||
|
||||
@Override
|
||||
public TextureRegion getIconRegion() {
|
||||
return mech.iconRegion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCapacity() {
|
||||
return mech.itemCapacity;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.anuke.mindustry.entities;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import io.anuke.mindustry.content.blocks.Blocks;
|
||||
import io.anuke.mindustry.entities.traits.*;
|
||||
@@ -287,6 +288,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract TextureRegion getIconRegion();
|
||||
public abstract int getItemCapacity();
|
||||
public abstract int getAmmoCapacity();
|
||||
public abstract float getArmor();
|
||||
|
||||
@@ -9,6 +9,8 @@ import io.anuke.mindustry.entities.Unit;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.net.In;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.entities.impl.TimedEntity;
|
||||
import io.anuke.ucore.entities.trait.DrawTrait;
|
||||
@@ -42,6 +44,14 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
|
||||
create(item, x, y, to, () -> {});
|
||||
}
|
||||
|
||||
@Remote(in = In.entities, called = Loc.server)
|
||||
public static void transferItemTo(Item item, int amount, float x, float y, Tile tile){
|
||||
for (int i = 0; i < Mathf.clamp(amount/3, 1, 8); i++) {
|
||||
Timers.run(i*3, () -> create(item, x, y, tile, () -> {}));
|
||||
}
|
||||
tile.entity.items.addItem(item, amount);
|
||||
}
|
||||
|
||||
public static void create(Item item, float fromx, float fromy, PosTrait to, Callable done){
|
||||
ItemTransfer tr = Pools.obtain(ItemTransfer.class);
|
||||
tr.item = item;
|
||||
|
||||
@@ -197,7 +197,9 @@ public interface BuilderTrait {
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
entity.addProgress(core.items, 1f / entity.recipe.cost * Timers.delta() * getBuildPower(tile));
|
||||
entity.lastBuilder = (Player)unit;
|
||||
if(unit instanceof Player){
|
||||
entity.lastBuilder = (Player)unit;
|
||||
}
|
||||
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f);
|
||||
getCurrentRequest().progress = entity.progress();
|
||||
}
|
||||
@@ -230,7 +232,7 @@ public interface BuilderTrait {
|
||||
}
|
||||
}
|
||||
|
||||
/**Draw placement effects for an entity.*/
|
||||
/**Draw placement effects for an entity. This includes mining*/
|
||||
default void drawBuilding(Unit unit){
|
||||
if(!isBuilding()){
|
||||
if(getMineTile() != null){
|
||||
@@ -294,8 +296,11 @@ public interface BuilderTrait {
|
||||
Draw.color(Color.LIGHT_GRAY, Color.WHITE, 1f-flashScl + Mathf.absin(Timers.time(), 0.5f, flashScl));
|
||||
Shapes.laser("minelaser", "minelaser-end", px, py, ex, ey);
|
||||
|
||||
Draw.color(Palette.accent);
|
||||
Lines.poly(tile.worldx(), tile.worldy(), 4, tilesize/2f * Mathf.sqrt2, Timers.time());
|
||||
if(unit instanceof Player && ((Player) unit).isLocal) {
|
||||
Draw.color(Palette.accent);
|
||||
Lines.poly(tile.worldx(), tile.worldy(), 4, tilesize / 2f * Mathf.sqrt2, Timers.time());
|
||||
}
|
||||
|
||||
Draw.color();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.anuke.mindustry.entities.units;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import io.anuke.annotations.Annotations.Loc;
|
||||
import io.anuke.annotations.Annotations.Remote;
|
||||
import io.anuke.mindustry.content.fx.ExplosionFx;
|
||||
@@ -19,6 +20,7 @@ import io.anuke.mindustry.world.meta.BlockFlag;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
@@ -49,6 +51,10 @@ public abstract class BaseUnit extends Unit{
|
||||
this.team = team;
|
||||
}
|
||||
|
||||
public UnitType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**internal constructor used for deserialization, DO NOT USE*/
|
||||
public BaseUnit(){}
|
||||
|
||||
@@ -121,6 +127,11 @@ public abstract class BaseUnit extends Unit{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureRegion getIconRegion() {
|
||||
return Draw.region(type.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCapacity() {
|
||||
return type.itemCapacity;
|
||||
|
||||
@@ -7,14 +7,12 @@ import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.graphics.Trail;
|
||||
import io.anuke.mindustry.type.AmmoType;
|
||||
import io.anuke.mindustry.type.ItemStack;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.meta.BlockFlag;
|
||||
import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.Translator;
|
||||
import io.anuke.ucore.util.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
@@ -54,7 +52,7 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
|
||||
public void update() {
|
||||
super.update();
|
||||
|
||||
rotation = velocity.angle();
|
||||
updateRotation();
|
||||
trail.update(x + Angles.trnsx(rotation + 180f, 6f) + Mathf.range(wobblyness),
|
||||
y + Angles.trnsy(rotation + 180f, 6f) + Mathf.range(wobblyness));
|
||||
}
|
||||
@@ -65,6 +63,21 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
|
||||
|
||||
Draw.rect(type.name, x, y, rotation - 90);
|
||||
|
||||
float backTrns = 4f, itemSize = 5f;
|
||||
if(inventory.hasItem()){
|
||||
ItemStack stack = inventory.getItem();
|
||||
int stored = Mathf.clamp(stack.amount / 6, 1, 8);
|
||||
|
||||
for(int i = 0; i < stored; i ++) {
|
||||
float angT = i == 0 ? 0 : Mathf.randomSeedRange(i + 2, 60f);
|
||||
float lenT = i == 0 ? 0 : Mathf.randomSeedRange(i + 3, 1f) - 1f;
|
||||
Draw.rect(stack.item.region,
|
||||
x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT),
|
||||
y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT),
|
||||
itemSize, itemSize, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
Draw.alpha(1f);
|
||||
}
|
||||
|
||||
@@ -107,14 +120,37 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{
|
||||
dropCarry();
|
||||
}
|
||||
|
||||
protected void updateRotation(){
|
||||
rotation = velocity.angle();
|
||||
}
|
||||
|
||||
protected void circle(float circleLength){
|
||||
circle(circleLength, type.speed);
|
||||
}
|
||||
|
||||
protected void circle(float circleLength, float speed){
|
||||
if(target == null) return;
|
||||
|
||||
vec.set(target.getX() - x, target.getY() - y);
|
||||
|
||||
if(vec.len() < circleLength){
|
||||
vec.rotate((circleLength-vec.len())/circleLength * 180f);
|
||||
}
|
||||
|
||||
vec.setLength(type.speed * Timers.delta());
|
||||
vec.setLength(speed * Timers.delta());
|
||||
|
||||
velocity.add(vec);
|
||||
}
|
||||
|
||||
protected void moveTo(float circleLength){
|
||||
if(target == null) return;
|
||||
|
||||
vec.set(target.getX() - x, target.getY() - y);
|
||||
|
||||
float length = Mathf.clamp((distanceTo(target) - circleLength)/100f, -1f, 1f);
|
||||
|
||||
vec.setLength(type.speed * Timers.delta() * length);
|
||||
if(length < 0) vec.rotate(180f);
|
||||
|
||||
velocity.add(vec);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public class UnitDrops {
|
||||
|
||||
public static void dropItems(BaseUnit unit){
|
||||
if(dropTable == null){
|
||||
dropTable = new Item[]{Items.iron, Items.lead, Items.steel};
|
||||
dropTable = new Item[]{Items.tungsten, Items.lead, Items.carbide};
|
||||
}
|
||||
|
||||
for(Item item : dropTable){
|
||||
|
||||
@@ -32,7 +32,8 @@ public class UnitType {
|
||||
public float armor = 0f;
|
||||
public float carryWeight = 1f;
|
||||
public int ammoCapacity = 100;
|
||||
public int itemCapacity = 100;
|
||||
public int itemCapacity = 30;
|
||||
public int mineLevel = 2;
|
||||
public ObjectMap<Item, AmmoType> ammo = new ObjectMap<>();
|
||||
|
||||
public UnitType(String name, UnitCreator creator){
|
||||
|
||||
@@ -12,7 +12,9 @@ import io.anuke.mindustry.entities.units.UnitState;
|
||||
import io.anuke.mindustry.entities.units.UnitType;
|
||||
import io.anuke.mindustry.game.EventType.BlockBuildEvent;
|
||||
import io.anuke.mindustry.game.Team;
|
||||
import io.anuke.mindustry.gen.CallEntity;
|
||||
import io.anuke.mindustry.graphics.Palette;
|
||||
import io.anuke.mindustry.type.Item;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.blocks.BuildBlock;
|
||||
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
|
||||
@@ -22,10 +24,7 @@ import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.EntityGroup;
|
||||
import io.anuke.ucore.graphics.Draw;
|
||||
import io.anuke.ucore.graphics.Shapes;
|
||||
import io.anuke.ucore.util.Angles;
|
||||
import io.anuke.ucore.util.Geometry;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
import io.anuke.ucore.util.ThreadQueue;
|
||||
import io.anuke.ucore.util.*;
|
||||
|
||||
import static io.anuke.mindustry.Vars.unitGroups;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
@@ -33,16 +32,22 @@ import static io.anuke.mindustry.Vars.world;
|
||||
public class Drone extends FlyingUnit implements BuilderTrait {
|
||||
public static int typeID = -1;
|
||||
|
||||
protected static Item[] toMine;
|
||||
protected static float healSpeed = 0.1f;
|
||||
protected static float discoverRange = 120f;
|
||||
protected static boolean initialized;
|
||||
|
||||
protected Item targetItem;
|
||||
protected Tile mineTile;
|
||||
protected Queue<BuildRequest> placeQueue = new ThreadQueue<>();
|
||||
|
||||
/**Initialize placement event notifier system.
|
||||
* Static initialization is to be avoided, thus, this is done lazily.*/
|
||||
private static void initEvents(){
|
||||
if(initialized) return;
|
||||
|
||||
toMine = new Item[]{Items.lead, Items.tungsten};
|
||||
|
||||
Events.on(BlockBuildEvent.class, (team, tile) -> {
|
||||
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
|
||||
|
||||
@@ -57,17 +62,15 @@ public class Drone extends FlyingUnit implements BuilderTrait {
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
initEvents();
|
||||
}
|
||||
|
||||
public Drone(UnitType type, Team team) {
|
||||
super(type, team);
|
||||
|
||||
if(!initialized){
|
||||
initEvents();
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
public Drone(){
|
||||
|
||||
}
|
||||
|
||||
private void notifyPlaced(BuildEntity entity){
|
||||
@@ -107,24 +110,25 @@ public class Drone extends FlyingUnit implements BuilderTrait {
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
float rot = rotation;
|
||||
super.update();
|
||||
rotation = rot;
|
||||
|
||||
if(target != null && state.is(repair)){
|
||||
rotation = Mathf.slerpDelta(rot, angleTo(target), 0.3f);
|
||||
}else{
|
||||
rotation = Mathf.slerpDelta(rot, velocity.angle(), 0.3f);
|
||||
}
|
||||
|
||||
x += Mathf.sin(Timers.time() + id * 999, 25f, 0.07f);
|
||||
y += Mathf.cos(Timers.time() + id * 999, 25f, 0.07f);
|
||||
|
||||
updateBuilding(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRotation() {
|
||||
if(target != null && (state.is(repair) || state.is(mine))){
|
||||
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.3f);
|
||||
}else{
|
||||
rotation = Mathf.slerpDelta(rotation, velocity.angle(), 0.3f);
|
||||
}
|
||||
|
||||
if(velocity.len() <= 0.2f && !(state.is(repair) && target != null)){
|
||||
rotation += Mathf.sin(Timers.time() + id * 99, 10f, 5f);
|
||||
}
|
||||
|
||||
updateBuilding(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -162,6 +166,14 @@ public class Drone extends FlyingUnit implements BuilderTrait {
|
||||
return isBuilding() ? placeDistance*2f : 30f;
|
||||
}
|
||||
|
||||
protected void findItem(){
|
||||
TileEntity entity = getClosestCore();
|
||||
if(entity == null){
|
||||
return;
|
||||
}
|
||||
targetItem = Mathf.findMin(toMine, (a, b) -> -Integer.compare(entity.items.getItem(a), entity.items.getItem(b)));
|
||||
}
|
||||
|
||||
public final UnitState
|
||||
|
||||
build = new UnitState(){
|
||||
@@ -211,19 +223,66 @@ public class Drone extends FlyingUnit implements BuilderTrait {
|
||||
}
|
||||
},
|
||||
mine = new UnitState() {
|
||||
public void entered() {
|
||||
setMineTile(null);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if(targetItem == null) {
|
||||
findItem();
|
||||
}
|
||||
|
||||
//if inventory is full, drop it off.
|
||||
if(inventory.isFull()){
|
||||
setState(drop);
|
||||
}else{
|
||||
//only mines iron for now
|
||||
retarget(() -> target = Geometry.findClosest(x, y, world.indexer().getOrePositions(Items.iron)));
|
||||
//only mines tungsten for now
|
||||
retarget(() -> {
|
||||
if(getMineTile() == null){
|
||||
findItem();
|
||||
}
|
||||
|
||||
if(targetItem == null) return;
|
||||
|
||||
target = world.indexer().findClosestOre(x, y, targetItem);
|
||||
});
|
||||
|
||||
if(target != null) {
|
||||
moveTo(type.range/1.5f);
|
||||
|
||||
if (distanceTo(target) < type.range) {
|
||||
setMineTile((Tile)target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void exited() {
|
||||
setMineTile(null);
|
||||
}
|
||||
},
|
||||
drop = new UnitState() {
|
||||
public void update() {
|
||||
|
||||
public void update() {
|
||||
if(inventory.isEmpty()){
|
||||
setState(mine);
|
||||
return;
|
||||
}
|
||||
|
||||
target = getClosestCore();
|
||||
|
||||
if(target == null) return;
|
||||
|
||||
TileEntity tile = (TileEntity)target;
|
||||
|
||||
if(distanceTo(target) < type.range
|
||||
&& tile.tile.block().acceptStack(inventory.getItem().item, inventory.getItem().amount, tile.tile, Drone.this) == inventory.getItem().amount){
|
||||
CallEntity.transferItemTo(inventory.getItem().item, inventory.getItem().amount, x, y, tile.tile);
|
||||
inventory.clearItem();
|
||||
setState(repair);
|
||||
}
|
||||
|
||||
circle(type.range/1.8f);
|
||||
}
|
||||
},
|
||||
retreat = new UnitState() {
|
||||
|
||||
Reference in New Issue
Block a user