Implemented conveyor item access
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user