Added core miner drone, massive amount of balancing/setup

This commit is contained in:
Anuken
2018-06-22 15:07:47 -04:00
parent 28e44d33c4
commit c24eb231ab
119 changed files with 1011 additions and 1104 deletions

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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){

View File

@@ -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){

View File

@@ -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() {