Implemented conveyor item access

This commit is contained in:
Anuken
2018-04-15 13:05:18 -04:00
parent 97e5ac4c1e
commit 01fc7108d8
8 changed files with 131 additions and 108 deletions

View File

@@ -544,7 +544,7 @@ public class Renderer extends RendererModule{
Tile tile = world.tileWorld(v.x, v.y);
if(tile != null) tile = tile.target();
if(tile != null && tile.block().acceptStack(player.inventory.getItem(), tile, player)){
if(tile != null && tile.block().acceptStack(player.inventory.getItem().item, player.inventory.getItem().amount, tile, player) > 0){
Draw.color("place");
Lines.square(tile.drawx(), tile.drawy(), tile.block().size*tilesize/2f + 1 + Mathf.absin(Timers.time(), 5f, 1f));
Draw.color();

View File

@@ -6,6 +6,7 @@ import io.anuke.mindustry.Vars;
import io.anuke.mindustry.resource.Item;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.TimedEntity;
import io.anuke.ucore.function.Callable;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf;
@@ -16,19 +17,27 @@ public class ItemAnimationEffect extends TimedEntity {
private final Vector2 from = new Vector2();
private final Vector2 to = new Vector2();
private final Item item;
private final Callable removed;
public Interpolation interp = Interpolation.fade;
public float endSize = 0.8f;
public float endSize = 0.9f;
public ItemAnimationEffect(Item item, float x, float y, float tox, float toy) {
public ItemAnimationEffect(Item item, float x, float y, float tox, float toy, Callable removed) {
this.x = x;
this.y = y;
this.item = item;
this.removed = removed;
from.set(x, y);
to.set(tox, toy);
lifetime = 40f;
}
@Override
public void removed() {
super.removed();
removed.run();
}
@Override
public void update() {
super.update();

View File

@@ -2,10 +2,8 @@ package io.anuke.mindustry.input;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.entities.ItemAnimationEffect;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents;
@@ -19,6 +17,7 @@ import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator;
import static io.anuke.mindustry.Vars.*;
@@ -34,6 +33,8 @@ public abstract class InputHandler extends InputAdapter{
public boolean shooting;
public float playerSelectRange = Unit.dp.scl(60f);
private Translator stackTrns = new Translator();
public abstract void update();
public abstract float getCursorX();
public abstract float getCursorY();
@@ -65,25 +66,36 @@ public abstract class InputHandler extends InputAdapter{
}
public void dropItem(Tile tile, ItemStack stack){
if(tile.block().acceptStack(stack, tile, player)){
int accepted = tile.block().acceptStack(stack.item, stack.amount, tile, player);
if(accepted > 0){
if(transferring) return;
transferring = true;
int accepted = tile.block().handleStack(stack, tile, player);
boolean clear = stack.amount == accepted;
float backTrns = 3f;
int sent = Mathf.clamp(accepted/4, 1, 8);
int removed = accepted/sent;
int[] remaining = {accepted};
int[] remaining = {accepted, accepted};
for(int i = 0; i < sent; i ++){
boolean end = i == sent-1;
Timers.run(i * 3, () -> {
tile.block().getStackOffset(stack.item, tile, stackTrns);
new ItemAnimationEffect(stack.item,
player.x + Angles.trnsx(rotation + 180f, backTrns), player.y + Angles.trnsy(rotation + 180f, backTrns),
tile.drawx(), tile.drawy()).add();
tile.drawx() + stackTrns.x, tile.drawy() + stackTrns.y, () -> {
tile.block().handleStack(stack.item, removed, tile, player);
remaining[1] -= removed;
if(end && remaining[1] > 0) {
tile.block().handleStack(stack.item, remaining[1], tile, player);
}
}).add();
stack.amount -= removed;
remaining[0] -= removed;
@@ -107,7 +119,7 @@ public abstract class InputHandler extends InputAdapter{
y = player.y + Angles.trnsy(rotation + 180f, backTrns);
ItemAnimationEffect e = new ItemAnimationEffect(stack.item,
x, y, x + Mathf.range(20f), y + Mathf.range(20f)).add();
x, y, x + Mathf.range(20f), y + Mathf.range(20f), () -> {}).add();
e.interp = Interpolation.pow3Out;
e.endSize = 0.5f;
e.lifetime = 20;
@@ -151,43 +163,10 @@ public abstract class InputHandler extends InputAdapter{
}
public boolean validPlace(int x, int y, Block type){
if(!type.isMultiblock() && control.tutorial().active() &&
control.tutorial().showBlock()){
//TODO placepoint control, make sure it's correct.
GridPoint2 point = control.tutorial().getPlacePoint();
int rotation = control.tutorial().getPlaceRotation();
Block block = control.tutorial().getPlaceBlock();
if(type != block || (rotation != -1 && rotation != this.rotation)){
return false;
}
}else if(control.tutorial().active()){
return false;
}
return Placement.validPlace(player.team, x, y, type, rotation);
}
public boolean validBreak(int x, int y){
if(control.tutorial().active()){
if(control.tutorial().showBlock()){
//TODO placepoint control, make sure it's correct
GridPoint2 point = control.tutorial().getPlacePoint();
int rotation = control.tutorial().getPlaceRotation();
Block block = control.tutorial().getPlaceBlock();
if(block != Blocks.air
|| (rotation != -1 && rotation != this.rotation)){
return false;
}
}else{
return false;
}
}
return Placement.validBreak(player.team, x, y);
}

View File

@@ -135,7 +135,7 @@ public class BlockInventoryFragment implements Fragment {
if(!canPick.get()) return;
if (items[f] > 0) {
int amount = Math.min(Inputs.keyDown("item_withdraw") ? items[f] : 1, player.inventory.itemCapacityUsed(item));
items[f] -= amount;
tile.block().removeStack(tile, item, amount);
int sent = Mathf.clamp(amount/3, 1, 8);
int per = Math.min(amount/sent, 5);

View File

@@ -3,9 +3,9 @@ package io.anuke.mindustry.world;
import com.badlogic.gdx.math.GridPoint2;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator;
public abstract class BaseBlock {
public boolean hasInventory = true;
@@ -17,15 +17,29 @@ public abstract class BaseBlock {
public float liquidFlowFactor = 4.9f;
public float powerCapacity = 10f;
public boolean acceptStack(ItemStack item, Tile tile, Unit source){
return acceptItem(item.item, tile, tile) && hasInventory && source.team == tile.getTeam();
/**Returns the amount of items this block can accept.*/
public int acceptStack(Item item, int amount, Tile tile, Unit source){
if(acceptItem(item, tile, tile) && hasInventory && source.team == tile.getTeam()){
return Math.min(itemCapacity - tile.entity.inventory.totalItems(), amount);
}else{
return 0;
}
}
public int handleStack(ItemStack item, Tile tile, Unit source){
int total = tile.entity.inventory.totalItems();
int canAccept = Math.min(itemCapacity - total, item.amount);
tile.entity.inventory.addItem(item.item, canAccept);
return canAccept;
/**Remove a stack from this inventory, and return the amount removed.*/
public int removeStack(Tile tile, Item item, int amount){
tile.entity.inventory.removeItem(item, amount);
return amount;
}
/**Handle a stack input.*/
public void handleStack(Item item, int amount, Tile tile, Unit source){
tile.entity.inventory.addItem(item, amount);
}
/**Returns offset for stack placement.*/
public void getStackOffset(Item item, Tile tile, Translator trns){
}
public void handleItem(Item item, Tile tile, Tile source){

View File

@@ -150,15 +150,13 @@ public class Placement {
return false;
}
public static boolean validBreak(Team team, int x, int y){
public static boolean validBreak(Team team, int x, int y) {
Tile tile = world.tile(x, y);
if(tile == null || tile.block().unbreakable) return false;
if (tile == null || tile.block().unbreakable) return false;
if(tile.isLinked() && tile.getLinked().block().unbreakable){
return false;
}
return (!tile.isLinked() || !tile.getLinked().block().unbreakable) && tile.breakable()
&& (tile.getTeam() == Team.none || tile.getTeam() == team);
return tile.breakable() && (tile.getTeam() == Team.none || tile.getTeam() == team);
}
}

View File

@@ -1,13 +1,13 @@
package io.anuke.mindustry.world.blocks.types.distribution;
import com.badlogic.gdx.utils.LongArray;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.BlockGroup;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
@@ -16,9 +16,6 @@ import io.anuke.ucore.util.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.AbstractList;
import java.util.Collections;
import java.util.List;
import static io.anuke.mindustry.Vars.tilesize;
@@ -26,11 +23,11 @@ public class Conveyor extends Block{
private static ItemPos drawpos = new ItemPos();
private static ItemPos pos1 = new ItemPos();
private static ItemPos pos2 = new ItemPos();
private static final float itemSpace = 0.135f * 2.2f;
private static final float offsetScl = 128f*3f;
private static final float minmove = 1f / (Short.MAX_VALUE - 2);
public static final float itemSize = 5f;
private static final float itemSize = 5f;
private final Translator tr1 = new Translator();
private final Translator tr2 = new Translator();
@@ -44,9 +41,12 @@ public class Conveyor extends Block{
update = true;
layer = Layer.overlay;
group = BlockGroup.transportation;
hasInventory = false;
hasInventory = true;
}
@Override
public void setBars() {}
@Override
public void setStats(){
super.setStats();
@@ -119,45 +119,46 @@ public class Conveyor extends Block{
}
@Override
public void update(Tile tile){
public synchronized void update(Tile tile){
ConveyorEntity entity = tile.entity();
entity.minitem = 1f;
int minremove = Integer.MAX_VALUE;
float speed = Math.max(this.speed - (1f - (carryCapacity - entity.carrying)/carryCapacity), 0f);
float speed = Math.max(this.speed - (1f - (carryCapacity - entity.carrying) / carryCapacity), 0f);
for(int i = entity.convey.size - 1; i >= 0; i --){
for (int i = entity.convey.size - 1; i >= 0; i--) {
long value = entity.convey.get(i);
ItemPos pos = pos1.set(value, ItemPos.updateShorts);
//..this should never happen, but in case it does, remove it and stop here
if(pos.item == null){
if (pos.item == null) {
entity.convey.removeValue(value);
break;
}
float nextpos = (i == entity.convey.size - 1 ? 100f : pos2.set(entity.convey.get(i + 1), ItemPos.updateShorts).y) - itemSpace;
if(entity.minCarry >= pos.y && entity.minCarry <= nextpos){
if (entity.minCarry >= pos.y && entity.minCarry <= nextpos) {
nextpos = entity.minCarry;
}
float maxmove = Math.min(nextpos - pos.y, speed * Timers.delta());
if(maxmove > minmove){
if (maxmove > minmove) {
pos.y += maxmove;
pos.x = Mathf.lerpDelta(pos.x, 0, 0.06f);
}else{
pos.x = Mathf.lerpDelta(pos.x, pos.seed/offsetScl, 0.1f);
} else {
pos.x = Mathf.lerpDelta(pos.x, pos.seed / offsetScl, 0.1f);
}
pos.y = Mathf.clamp(pos.y);
if(pos.y >= 0.9999f && offloadDir(tile, pos.item)){
if (pos.y >= 0.9999f && offloadDir(tile, pos.item)) {
minremove = Math.min(i, minremove);
}else{
tile.entity.inventory.removeItem(pos.item, 1);
} else {
value = pos.pack();
if(pos.y < entity.minitem)
if (pos.y < entity.minitem)
entity.minitem = pos.y;
entity.convey.set(i, value);
}
@@ -166,12 +167,53 @@ public class Conveyor extends Block{
entity.carrying = 0f;
entity.minCarry = 2f;
if(minremove != Integer.MAX_VALUE) entity.convey.truncate(minremove);
if (minremove != Integer.MAX_VALUE) entity.convey.truncate(minremove);
}
@Override
public TileEntity getEntity(){
return new ConveyorEntity();
public boolean isAccessible(){
return true;
}
@Override
public synchronized int removeStack(Tile tile, Item item, int amount) {
ConveyorEntity entity = tile.entity();
int removed = 0;
for(int j = 0; j < amount; j ++) {
for (int i = 0; i < entity.convey.size; i++) {
long val = entity.convey.get(i);
ItemPos pos = pos1.set(val, ItemPos.drawShorts);
if(pos.item == item){
entity.convey.removeValue(val);
entity.inventory.removeItem(item, 1);
removed ++;
break;
}
}
}
return removed;
}
@Override
public void getStackOffset(Item item, Tile tile, Translator trns) {
trns.trns(tile.getRotation()*90 + 180f, tilesize/2f);
}
@Override
public synchronized int acceptStack(Item item, int amount, Tile tile, Unit source) {
ConveyorEntity entity = tile.entity();
return entity.minitem > itemSpace ? 1 : 0;
}
@Override
public synchronized void handleStack(Item item, int amount, Tile tile, Unit source) {
ConveyorEntity entity = tile.entity();
long result = ItemPos.packItem(item, 0f, 0f, (byte)Mathf.random(255));
entity.convey.insert(0, result);
entity.inventory.addItem(item, 1);
}
@Override
@@ -196,6 +238,8 @@ public class Conveyor extends Block{
long result = ItemPos.packItem(item, y*0.9f, pos, (byte)Mathf.random(255));
boolean inserted = false;
tile.entity.inventory.addItem(item, 1);
for(int i = 0; i < entity.convey.size; i ++){
if(compareItems(result, entity.convey.get(i)) < 0){
entity.convey.insert(i, result);
@@ -210,6 +254,11 @@ public class Conveyor extends Block{
}
}
@Override
public TileEntity getEntity(){
return new ConveyorEntity();
}
public static class ConveyorEntity extends TileEntity{
LongArray convey = new LongArray();
@@ -235,35 +284,9 @@ public class Conveyor extends Block{
for(int i = 0; i < amount; i ++){
convey.add(ItemPos.toLong(stream.readInt()));
}
sort(convey.items, convey.size);
}
}
private static void sort(long[] elements, int length){
List<Long> wrapper = new AbstractList<Long>() {
@Override
public Long get(int index) {
return elements[index];
}
@Override
public int size() {
return length;
}
@Override
public Long set(int index, Long element) {
long v = elements[index];
elements[index] = element;
return v;
}
};
Collections.sort(wrapper, Conveyor::compareItems);
}
private static int compareItems(Long a, Long b){
pos1.set(a, ItemPos.packShorts);
pos2.set(b, ItemPos.packShorts);