1
0
Fork 0

add basic energy system

This commit is contained in:
Sen 2025-08-14 17:16:39 +02:00
parent b4daadcb45
commit 69bb1e6ffb
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
12 changed files with 284 additions and 196 deletions

View file

@ -4,7 +4,7 @@ import common.item.ItemStack;
import common.util.Facing; import common.util.Facing;
public interface ISidedInventory extends IInventory { public interface ISidedInventory extends IInventory {
int[] getSlotsForFace(Facing side); int getSlotForFace(Facing side);
boolean canInsertItem(int index, ItemStack stack, Facing side); boolean canInsertItem(int index, ItemStack stack);
boolean canExtractItem(int index, ItemStack stack, Facing side); boolean canExtractItem(int index);
} }

View file

@ -1,19 +1,27 @@
package common.tileentity; package common.tileentity;
import common.block.ITileEntityProvider;
import common.block.tech.BlockMachine;
import common.collect.Lists; import common.collect.Lists;
import common.entity.npc.EntityNPC; import common.entity.npc.EntityNPC;
import common.inventory.ContainerTile; import common.inventory.ContainerTile;
import common.inventory.IInventory; import common.inventory.IInventory;
import common.inventory.ISidedInventory;
import common.item.ItemStack; import common.item.ItemStack;
import common.network.Packet; import common.network.Packet;
import common.packet.SPacketUpdateDevice; import common.packet.SPacketUpdateDevice;
import common.rng.Random; import common.rng.Random;
import common.tags.TagObject; import common.tags.TagObject;
import common.tileentity.MachineResource.Type;
import java.util.Arrays;
import java.util.List; import java.util.List;
import common.util.ExtMath; import common.util.ExtMath;
import common.util.Facing;
import common.vars.Vars;
import common.util.Color; import common.util.Color;
public abstract class Device extends TileEntity implements IInventory, ITickable { public abstract class Device extends TileEntity implements IInventory, ITickable, ISidedInventory, IConverter {
public static enum Status { public static enum Status {
OFF(Color.GRAY, "Inaktiv"), OFF(Color.GRAY, "Inaktiv"),
COOLING(Color.YELLOW, "Abkühlen ..."), COOLING(Color.YELLOW, "Abkühlen ..."),
@ -32,6 +40,7 @@ public abstract class Device extends TileEntity implements IInventory, ITickable
protected final ItemStack[] inventory; protected final ItemStack[] inventory;
protected final MachineResource[] resources; protected final MachineResource[] resources;
protected final int[] slotSides = new int[Facing.values().length];
protected final Random rand = new Random(); protected final Random rand = new Random();
protected final int inputs; protected final int inputs;
protected int temperature; protected int temperature;
@ -43,6 +52,16 @@ public abstract class Device extends TileEntity implements IInventory, ITickable
this.inventory = new ItemStack[inputs + outputs]; this.inventory = new ItemStack[inputs + outputs];
this.inputs = inputs; this.inputs = inputs;
this.resources = resources; this.resources = resources;
Arrays.fill(this.slotSides, -1);
for(int z = 0; z < this.inventory.length; z++) {
Facing side = this.getDefaultSide(z);
if(side != null)
this.slotSides[side.ordinal()] = z;
}
}
protected Facing getDefaultSide(int slot) {
return null;
} }
protected int getTempIncrement() { protected int getTempIncrement() {
@ -243,7 +262,7 @@ public abstract class Device extends TileEntity implements IInventory, ITickable
else else
this.temperature += this.getTempIncrement(); this.temperature += this.getTempIncrement();
this.status = this.temperature >= (this.getMaxTemp() * 9) / 10 ? Status.OVERHEAT : Status.RUNNING; this.status = this.temperature >= (this.getMaxTemp() * 9) / 10 ? Status.OVERHEAT : Status.RUNNING;
if(this.temperature > this.getMaxTemp()) { if(Vars.deviceExplosions && this.temperature > this.getMaxTemp()) {
this.status = Status.BROKEN; this.status = Status.BROKEN;
this.markDirty(); this.markDirty();
this.detonate(); this.detonate();
@ -325,4 +344,57 @@ public abstract class Device extends TileEntity implements IInventory, ITickable
public String formatDisplay(ContainerTile inv) { public String formatDisplay(ContainerTile inv) {
return ""; return "";
} }
public int getSlotForFace(Facing side) {
// return this.slotSides[side.ordinal()];
if(!(this.getState().getBlock() instanceof BlockMachine))
return -1;
return this.slotSides[(side.getAxis().isHorizontal() ? Facing.getHorizontal((side.getHorizontalIndex() + 2 + this.getState().getValue(BlockMachine.FACING).getHorizontalIndex()) % 4) : side).ordinal()];
}
public boolean canInsertItem(int index, ItemStack stack) {
return this.isInput(index);
}
public boolean canExtractItem(int index) {
return !this.isInput(index);
}
public int addEnergy(int amount) {
boolean changed = false;
for(int z = 0; z < this.getNumResources(); z++) {
MachineResource res = this.getResource(z);
if(res.getType() == Type.INPUT) {
int add = Math.min(res.getCapacity() - res.getValue(), amount);
if(add > 0) {
res.add(add, 0, false);
amount -= add;
changed = true;
if(amount <= 0)
break;
}
}
}
if(changed)
this.markDirty();
return amount;
}
public boolean pushResource(int index, Facing side) {
int amount = this.getResource(index).getValue();
if(amount <= 0)
return false;
if(this.world.getState(this.pos.offset(side)).getBlock() instanceof ITileEntityProvider) {
TileEntity te = this.world.getTileEntity(this.pos.offset(side));
if(te instanceof IConverter conv) {
int newAmt = conv.addEnergy(amount);
if(newAmt != amount) {
this.getResource(index).setValue(newAmt);
this.markDirty();
return true;
}
}
}
return false;
}
} }

View file

@ -6,6 +6,7 @@ import common.init.Items;
import common.item.Item; import common.item.Item;
import common.item.ItemStack; import common.item.ItemStack;
import common.item.consumable.ItemPotion; import common.item.consumable.ItemPotion;
import common.util.Facing;
public class DeviceBrewer extends Device { public class DeviceBrewer extends Device {
private Item lastItem; private Item lastItem;
@ -105,4 +106,8 @@ public class DeviceBrewer extends Device {
public boolean isItemValidForSlot(int index, ItemStack stack) { public boolean isItemValidForSlot(int index, ItemStack stack) {
return index == 1 ? BrewingRegistry.isIngredient(stack) : (index == 0 ? stack.getItem() instanceof ItemPotion || stack.getItem() == Items.bottle : false); return index == 1 ? BrewingRegistry.isIngredient(stack) : (index == 0 ? stack.getItem() instanceof ItemPotion || stack.getItem() == Items.bottle : false);
} }
protected Facing getDefaultSide(int slot) {
return slot == 0 ? Facing.EAST : (slot == 1 ? Facing.SOUTH : (slot == 2 ? Facing.WEST : null));
}
} }

View file

@ -4,6 +4,7 @@ import common.block.tech.BlockDispenser;
import common.item.ItemStack; import common.item.ItemStack;
import common.rng.Random; import common.rng.Random;
import common.tags.TagObject; import common.tags.TagObject;
import common.tileentity.MachineResource.Type;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.Facing; import common.util.Facing;
import common.vars.Vars; import common.vars.Vars;
@ -18,7 +19,7 @@ public class DeviceDispenser extends Device {
private int cooldown = 0; private int cooldown = 0;
public DeviceDispenser(boolean dropItems) { public DeviceDispenser(boolean dropItems) {
super(1, 0); super(1, 0, new MachineResource(Type.INPUT, "Energie: $amount/$capacity TF", 32));
this.dropItems = dropItems; this.dropItems = dropItems;
} }
@ -59,10 +60,10 @@ public class DeviceDispenser extends Device {
public boolean executeFunction() { public boolean executeFunction() {
if(this.cooldown <= 0) { if(this.cooldown <= 0) {
State state = this.getState(); State state = this.getState();
if(!(state.getBlock() instanceof BlockDispenser) /* || !this.decrPower() */) // TODO: energy if(!(state.getBlock() instanceof BlockDispenser))
return false; return false;
ItemStack stack = this.getStackInSlot(0); ItemStack stack = this.getStackInSlot(0);
if(stack != null) { if(stack != null && this.getResource(0).take(2, false)) {
ItemStack nstack = this.dispenseStack(stack, (AWorldServer)this.world, this.pos); ItemStack nstack = this.dispenseStack(stack, (AWorldServer)this.world, this.pos);
this.setInventorySlotContents(0, nstack != null && nstack.isEmpty() ? null : nstack); this.setInventorySlotContents(0, nstack != null && nstack.isEmpty() ? null : nstack);
this.cooldown = Vars.dispenserDelay; this.cooldown = Vars.dispenserDelay;
@ -75,4 +76,8 @@ public class DeviceDispenser extends Device {
return true; return true;
} }
} }
protected Facing getDefaultSide(int slot) {
return slot == 0 ? Facing.SOUTH : null;
}
} }

View file

@ -4,27 +4,29 @@ import java.util.List;
import common.effect.StatusEffect; import common.effect.StatusEffect;
import common.entity.npc.EntityNPC; import common.entity.npc.EntityNPC;
import common.init.Items;
import common.inventory.ContainerTile; import common.inventory.ContainerTile;
import common.item.ItemStack; import common.item.ItemStack;
import common.item.consumable.ItemPotion; import common.item.consumable.ItemPotion;
import common.tileentity.MachineResource.Type;
import common.util.BoundingBox; import common.util.BoundingBox;
import common.util.Facing;
import common.world.World; import common.world.World;
public class DeviceEffectGenerator extends Device { public class DeviceEffectGenerator extends Device {
public DeviceEffectGenerator() { public DeviceEffectGenerator() {
super(2, 0); super(1, 0, new MachineResource(Type.INPUT, "Energie: $amount/$capacity TF", 128));
} }
public boolean isItemValidForSlot(int index, ItemStack stack) { public boolean isItemValidForSlot(int index, ItemStack stack) {
return index == 0 ? stack.getItem() instanceof ItemPotion potion && potion.getEffect() != null : (index == 1 ? stack.getItem() == Items.blazing_powder : false); return index == 0 && stack.getItem() instanceof ItemPotion potion && potion.getEffect() != null;
} }
protected boolean executeFunction() { protected boolean executeFunction() {
if(!this.hasInput(0, 1) || !this.hasInput(1, 1) || !(this.getStackInSlot(0).getItem() instanceof ItemPotion potion)) if(!this.hasInput(0, 1) || !(this.getStackInSlot(0).getItem() instanceof ItemPotion potion))
return false; return false;
StatusEffect effect = potion.getEffect(); StatusEffect effect = potion.getEffect();
if(effect == null || !this.hasInput(1, effect.getAmplifier() + 1)) int energy = 8 + 6 * effect.getAmplifier();
if(effect == null || this.getResource(0).getValue() < energy)
return false; return false;
int levels = 4; // TODO: energy + selector (MachineControl) int levels = 4; // TODO: energy + selector (MachineControl)
double r = (double)(levels * 10 + 10); double r = (double)(levels * 10 + 10);
@ -36,8 +38,8 @@ public class DeviceEffectGenerator extends Device {
for(EntityNPC entity : list) { for(EntityNPC entity : list) {
if(!entity.hasEffect(effect.getPotion()) || entity.getEffect(effect.getPotion()).getAmplifier() < effect.getAmplifier() || entity.getEffect(effect.getPotion()).getRemaining() < 40) { if(!entity.hasEffect(effect.getPotion()) || entity.getEffect(effect.getPotion()).getAmplifier() < effect.getAmplifier() || entity.getEffect(effect.getPotion()).getRemaining() < 40) {
entity.addEffect(new StatusEffect(effect.getPotion(), 180, effect.getAmplifier())); entity.addEffect(new StatusEffect(effect.getPotion(), 180, effect.getAmplifier()));
this.decrStackSize(1, effect.getAmplifier() + 1); this.getResource(0).take(energy, false);
if(!this.hasInput(1, effect.getAmplifier() + 1)) if(this.getResource(0).getValue() < energy)
break; break;
} }
} }
@ -54,4 +56,8 @@ public class DeviceEffectGenerator extends Device {
return "Trank einlegen"; return "Trank einlegen";
return "Gebe Effekt " + (stack.getItem() instanceof ItemPotion potion && potion.getEffect() != null ? potion.getEffect().getEffectName() : "<?>"); return "Gebe Effekt " + (stack.getItem() instanceof ItemPotion potion && potion.getEffect() != null ? potion.getEffect().getEffectName() : "<?>");
} }
protected Facing getDefaultSide(int slot) {
return slot == 0 ? Facing.SOUTH : null;
}
} }

View file

@ -4,7 +4,6 @@ import common.block.Block;
import common.block.tech.BlockFurnace; import common.block.tech.BlockFurnace;
import common.init.Items; import common.init.Items;
import common.init.SmeltingRegistry; import common.init.SmeltingRegistry;
import common.inventory.ISidedInventory;
import common.item.Item; import common.item.Item;
import common.item.ItemStack; import common.item.ItemStack;
import common.tags.TagObject; import common.tags.TagObject;
@ -14,17 +13,13 @@ import common.util.ExtMath;
import common.util.Facing; import common.util.Facing;
import common.vars.Vars; import common.vars.Vars;
public class DeviceFurnace extends Device implements ISidedInventory public class DeviceFurnace extends Device
{ {
private static final int[] slotsTop = new int[] {0};
private static final int[] slotsBottom = new int[] {2, 1};
private static final int[] slotsSides = new int[] {1};
private final int burnTime; private final int burnTime;
private final int fuelEfficiency; private final int fuelEfficiency;
public DeviceFurnace(int burnTime, int fuelEfficiency) { public DeviceFurnace(int burnTime, int fuelEfficiency) {
super(2, 1, new MachineResource(Type.FUEL, "Brennzeit: $amount/$capacity t", 300, 0, 0)); super(2, 1, new MachineResource(Type.FUEL, "Brennzeit: $amount/$capacity t", 300));
this.burnTime = burnTime; this.burnTime = burnTime;
this.fuelEfficiency = fuelEfficiency; this.fuelEfficiency = fuelEfficiency;
} }
@ -188,28 +183,11 @@ public class DeviceFurnace extends Device implements ISidedInventory
return index == 2 ? false : (index != 1 ? true : isItemFuel(stack)); return index == 2 ? false : (index != 1 ? true : isItemFuel(stack));
} }
public int[] getSlotsForFace(Facing side) public boolean canExtractItem(int index) {
{ return super.canExtractItem(index) && (index != 1 || this.getStackInSlot(index).getItem() == Items.bucket);
return side == Facing.DOWN ? slotsBottom : (side == Facing.UP ? slotsTop : slotsSides); }
}
public boolean canInsertItem(int index, ItemStack itemStackIn, Facing direction) protected Facing getDefaultSide(int slot) {
{ return slot == 0 ? Facing.EAST : (slot == 1 ? Facing.SOUTH : (slot == 2 ? Facing.WEST : null));
return this.isItemValidForSlot(index, itemStackIn); }
}
public boolean canExtractItem(int index, ItemStack stack, Facing direction)
{
if (direction == Facing.DOWN && index == 1)
{
Item item = stack.getItem();
if (item != Items.bucket)
{
return false;
}
}
return true;
}
} }

View file

@ -7,12 +7,14 @@ import common.item.ItemStack;
import common.item.spawner.ItemMobTemplate; import common.item.spawner.ItemMobTemplate;
import common.item.spawner.ItemCharTemplate; import common.item.spawner.ItemCharTemplate;
import common.tags.TagObject; import common.tags.TagObject;
import common.tileentity.MachineResource.Type;
import common.util.Facing;
import common.vars.Vars; import common.vars.Vars;
public class DeviceMobSpawner extends Device public class DeviceMobSpawner extends Device
{ {
public DeviceMobSpawner() { public DeviceMobSpawner() {
super(1, 0); super(1, 0, new MachineResource(Type.INPUT, "Energie: $amount/$capacity TF", 128));
} }
private int spawnDelay = 20; private int spawnDelay = 20;
@ -21,7 +23,7 @@ public class DeviceMobSpawner extends Device
private int spawnRange = 4; private int spawnRange = 4;
public boolean isItemValidForSlot(int index, ItemStack stack) { public boolean isItemValidForSlot(int index, ItemStack stack) {
return index == 0 ? stack.getItem() instanceof ItemMobTemplate || stack.getItem() instanceof ItemCharTemplate : false; return index == 0 && (stack.getItem() instanceof ItemMobTemplate || stack.getItem() instanceof ItemCharTemplate);
} }
public String formatDisplay(ContainerTile inv) { public String formatDisplay(ContainerTile inv) {
@ -32,7 +34,7 @@ public class DeviceMobSpawner extends Device
} }
protected boolean executeFunction() { protected boolean executeFunction() {
if(!Vars.mobs || !Vars.spawners || !this.hasInput(0, 1)) if(!Vars.mobs || !Vars.spawners || !this.hasInput(0, 1) || this.getResource(0).getValue() < 32)
return false; return false;
if (this.spawnDelay == -1) if (this.spawnDelay == -1)
this.resetTimer(); this.resetTimer();
@ -53,7 +55,7 @@ public class DeviceMobSpawner extends Device
entity = ItemCharTemplate.spawnNpc(this.world, egg.getSpawnedChar(), x, y, z, true); entity = ItemCharTemplate.spawnNpc(this.world, egg.getSpawnedChar(), x, y, z, true);
if (entity == null) if (entity == null)
return true; return true;
this.decrStackSize(0, 1); this.getResource(0).take(32, false);
entity.spawnExplosionParticle(); entity.spawnExplosionParticle();
this.resetTimer(); this.resetTimer();
return true; return true;
@ -97,4 +99,8 @@ public class DeviceMobSpawner extends Device
tag.setShort("MaxSpawnDelay", (short)this.maxSpawnDelay); tag.setShort("MaxSpawnDelay", (short)this.maxSpawnDelay);
tag.setShort("SpawnRange", (short)this.spawnRange); tag.setShort("SpawnRange", (short)this.spawnRange);
} }
protected Facing getDefaultSide(int slot) {
return slot == 0 ? Facing.SOUTH : null;
}
} }

View file

@ -1,25 +1,30 @@
package common.tileentity; package common.tileentity;
import common.block.tech.BlockMachine;
import common.init.Items; import common.init.Items;
import common.inventory.ContainerTile; import common.inventory.ContainerTile;
import common.item.ItemStack; import common.item.ItemStack;
import common.tileentity.MachineResource.Type; import common.tileentity.MachineResource.Type;
import common.util.Color; import common.util.Color;
import common.util.Facing;
public class DeviceTianReactor extends Device { public class DeviceTianReactor extends Device {
public DeviceTianReactor() { public DeviceTianReactor() {
super(2, 0, new MachineResource(Type.OUTPUT, "Gespeichert: $amount/$capacity TF", 1024, 0, 0)); super(2, 0, new MachineResource(Type.OUTPUT, "Gespeichert: $amount/$capacity TF", 1024));
} }
protected boolean executeFunction() { protected boolean executeFunction() {
if(!this.hasInput(0, 2)) boolean flag;
return false; if(flag = this.hasInput(0, 2)) {
if(this.rand.rarity(5)) if(this.rand.chance(5)) {
return true; this.decrStackSize(0, 2);
this.decrStackSize(0, 2); this.decrStackSize(1, 1);
this.decrStackSize(1, 1); this.getResource(0).add(this.rand.range(this.temperature / 200, this.temperature / 50), 20, false);
this.getResource(0).add(this.rand.range(this.temperature / 200, this.temperature / 50), 20, false); }
return true; }
if(this.getState().getBlock() instanceof BlockMachine)
this.pushResource(0, this.getState().getValue(BlockMachine.FACING).getOpposite());
return flag;
} }
public boolean hasTemperature() { public boolean hasTemperature() {
@ -50,4 +55,8 @@ public class DeviceTianReactor extends Device {
public String formatDisplay(ContainerTile inv) { public String formatDisplay(ContainerTile inv) {
return this.status == Status.OVERHEAT ? Color.RED + "!!! GEFAHR !!! Reaktor ist\n" + Color.RED + "überhitzt und muss sofort\n" + Color.RED + "heruntergekühlt werden,\n" + Color.RED + "sonst droht Detonation!" : ""; return this.status == Status.OVERHEAT ? Color.RED + "!!! GEFAHR !!! Reaktor ist\n" + Color.RED + "überhitzt und muss sofort\n" + Color.RED + "heruntergekühlt werden,\n" + Color.RED + "sonst droht Detonation!" : "";
} }
protected Facing getDefaultSide(int slot) {
return slot == 0 ? Facing.EAST : (slot == 1 ? Facing.SOUTH : null);
}
} }

View file

@ -0,0 +1,5 @@
package common.tileentity;
public interface IConverter {
int addEnergy(int amount);
}

View file

@ -23,6 +23,10 @@ public class MachineResource {
this.overcharge = over; this.overcharge = over;
} }
public MachineResource(Type type, String name, int cap) {
this(type, name, cap, 0, 0);
}
public void fromTag(TagObject tag) { public void fromTag(TagObject tag) {
this.amount = tag.getInt("Amount"); this.amount = tag.getInt("Amount");
this.capacity = tag.getInt("Capacity"); this.capacity = tag.getInt("Capacity");
@ -78,6 +82,10 @@ public class MachineResource {
return true; return true;
} }
public Type getType() {
return this.type;
}
public int getValue() { public int getValue() {
return this.amount; return this.amount;
} }

View file

@ -23,7 +23,7 @@ import common.util.Serverside;
import common.vars.Vars; import common.vars.Vars;
import common.world.State; import common.world.State;
public class TileEntityItemPipe extends TileEntity implements IInventory, ITickable { public class TileEntityItemPipe extends TileEntity implements IInventory, ITickable, IConverter {
private final boolean suck; private final boolean suck;
private ItemStack stack = null; private ItemStack stack = null;
@ -31,7 +31,10 @@ public class TileEntityItemPipe extends TileEntity implements IInventory, ITicka
private ItemStack last = null; private ItemStack last = null;
private ItemStack display = null; private ItemStack display = null;
private ItemStack prevDisplay = null; private ItemStack prevDisplay = null;
private int cooldown = -1; private int inCooldown = 0;
private int outCooldown = 0;
private int power = 0;
private int suction = 0;
public TileEntityItemPipe(boolean suck) { public TileEntityItemPipe(boolean suck) {
this.suck = suck; this.suck = suck;
@ -47,13 +50,19 @@ public class TileEntityItemPipe extends TileEntity implements IInventory, ITicka
public void readTags(TagObject tag) { public void readTags(TagObject tag) {
super.readTags(tag); super.readTags(tag);
this.cooldown = tag.getInt("Cooldown"); this.inCooldown = tag.getInt("InCooldown");
this.outCooldown = tag.getInt("OutCooldown");
this.power = tag.getInt("Power");
this.suction = tag.getInt("Suction");
this.stack = ItemStack.readFromTag(tag.getObject("Item")); this.stack = ItemStack.readFromTag(tag.getObject("Item"));
} }
public void writeTags(TagObject tag) { public void writeTags(TagObject tag) {
super.writeTags(tag); super.writeTags(tag);
tag.setInt("Cooldown", this.cooldown); tag.setInt("InCooldown", this.inCooldown);
tag.setInt("OutCooldown", this.outCooldown);
tag.setInt("Power", this.power);
tag.setInt("Suction", this.suction);
if(this.stack != null) { if(this.stack != null) {
TagObject item = new TagObject(); TagObject item = new TagObject();
this.stack.writeTags(item); this.stack.writeTags(item);
@ -109,65 +118,60 @@ public class TileEntityItemPipe extends TileEntity implements IInventory, ITicka
public void clear() { public void clear() {
this.stack = null; this.stack = null;
} }
public void addSuction(int suction) {
this.suction = Math.max(suction, this.suction);
this.markDirty();
}
public void update() { public void update() {
if(this.world != null && !this.world.client) { if(this.world != null && !this.world.client) {
this.prevDisplay = this.display; this.prevDisplay = this.display;
this.display = ItemStack.copy(this.stack); this.display = ItemStack.copy(this.stack);
if(this.getState().getBlock() instanceof BlockPipe) {
--this.cooldown; boolean changed = false;
if(!this.isOnTransferCooldown()) { if(this.suction > 1) {
this.setTransferCooldown(0); BlockPos pos = this.pos.offset(this.getState().getValue(BlockPipe.FACING));
this.transferItems(); if(this.world.getState(pos).getBlock() instanceof ITileEntityProvider) {
TileEntity te = this.world.getTileEntity(pos);
if(te instanceof TileEntityItemPipe pipe)
pipe.addSuction(this.suction - 1);
}
}
if(this.power >= 8) {
this.power -= 8;
this.suction = 32;
changed = true;
}
else if(this.suction > 0) {
--this.suction;
changed = true;
}
if(this.suction > 0 || changed) {
if(--this.outCooldown <= 0) {
this.outCooldown = 0;
if(this.stack != null && this.transferOut()) {
this.outCooldown = Vars.pipeOutDelay;
changed = true;
}
}
if(--this.inCooldown <= 0) {
this.inCooldown = 0;
if((this.stack == null || !this.stack.isFull()) && this.transferIn()) {
this.inCooldown = Vars.pipeInDelay;
changed = true;
}
}
}
if(changed)
this.markDirty();
} }
if(!ItemStack.allEquals(this.last, this.getDisplayedItem())) if(!ItemStack.allEquals(this.last, this.getDisplayedItem()))
this.world.markBlockForUpdate(this.pos); this.world.markBlockForUpdate(this.pos);
this.last = this.getDisplayedItem(); this.last = this.getDisplayedItem();
} }
} }
protected boolean transferItems() {
if(!(this.getState().getBlock() instanceof BlockPipe) /* || !this.decrPower() */) // TODO: power
return false;
boolean flag = false;
if(!this.isEmpty()) {
flag = this.transferOut();
}
if(!this.isFull()) {
flag |= this.transferIn();
}
if(flag) {
this.setTransferCooldown(Vars.pipeDelay);
this.markDirty();
}
return flag;
}
private boolean isEmpty() {
return this.stack == null;
}
private boolean isFull() {
return this.stack != null && this.stack.isFull();
}
public void setTransferCooldown(int ticks) {
this.cooldown = ticks;
}
public boolean isOnTransferCooldown() {
return this.cooldown > 0;
}
//
// public boolean mayTransfer() {
// return this.cooldown <= 1;
// }
public int getColor() { public int getColor() {
return 0x0040ff; return 0x0040ff;
} }
@ -175,19 +179,27 @@ public class TileEntityItemPipe extends TileEntity implements IInventory, ITicka
public Packet getDescriptionPacket() { public Packet getDescriptionPacket() {
return new SPacketUpdatePipe(this); return new SPacketUpdatePipe(this);
} }
public int addEnergy(int amount) {
int add = Math.min(64 - this.power, amount);
if(add > 0) {
this.power += add;
amount -= add;
this.markDirty();
}
return amount;
}
// out // out
private static boolean isInventoryFull(IInventory inv, Facing side) { private static boolean isInventoryFull(IInventory inv, Facing side) {
if(inv instanceof ISidedInventory sided) { if(inv instanceof ISidedInventory sided) {
int[] sides = sided.getSlotsForFace(side); int slot = sided.getSlotForFace(side);
for(int k = 0; k < sides.length; ++k) { if(slot >= 0) {
ItemStack stack = sided.getStackInSlot(sides[k]); ItemStack stack = sided.getStackInSlot(slot);
if(stack == null || !stack.isFull())
if(stack == null || !stack.isFull()) {
return false; return false;
}
} }
} }
else { else {
@ -233,13 +245,10 @@ public class TileEntityItemPipe extends TileEntity implements IInventory, ITicka
private static boolean isInventoryEmpty(IInventory inv, Facing side) { private static boolean isInventoryEmpty(IInventory inv, Facing side) {
if(inv instanceof ISidedInventory sided) { if(inv instanceof ISidedInventory sided) {
int[] slots = sided.getSlotsForFace(side); int slot = sided.getSlotForFace(side);
for(int i = 0; i < slots.length; ++i) { if(slot >= 0 && sided.getStackInSlot(slot) != null)
if(sided.getStackInSlot(slots[i]) != null) { return false;
return false;
}
}
} }
else { else {
int size = inv.getSizeInventory(); int size = inv.getSizeInventory();
@ -254,38 +263,34 @@ public class TileEntityItemPipe extends TileEntity implements IInventory, ITicka
return true; return true;
} }
private static boolean putDropInInventoryAllSlots(IInventory p_145898_0_, EntityItem itemIn) { private boolean insertDrop(EntityItem entity) {
boolean flag = false; boolean flag = false;
if(itemIn == null) { if(entity == null) {
return false; return false;
} }
else { else {
ItemStack itemstack = itemIn.getEntityItem().copy(); ItemStack current = entity.getEntityItem().copy();
ItemStack itemstack1 = putStackInInventoryAllSlots(p_145898_0_, itemstack, (Facing)null); ItemStack remain = putStackInInventoryAllSlots(this, current, null);
if(itemstack1 != null && !itemstack1.isEmpty()) { if(remain != null && !remain.isEmpty()) {
itemIn.setEntityItemStack(itemstack1); entity.setEntityItemStack(remain);
} }
else { else {
flag = true; flag = true;
itemIn.setDead(); entity.setDead();
} }
return flag; return flag;
} }
} }
private static boolean canExtractItemFromSlot(IInventory inventoryIn, ItemStack stack, int index, Facing side) {
return !(inventoryIn instanceof ISidedInventory) || ((ISidedInventory)inventoryIn).canExtractItem(index, stack, side);
}
private boolean pullItemFromSlot(IInventory inventoryIn, int index, Facing direction) { private boolean pullItemFromSlot(IInventory inventoryIn, int index, Facing direction) {
ItemStack itemstack = inventoryIn.getStackInSlot(index); ItemStack itemstack = inventoryIn.getStackInSlot(index);
if(itemstack != null && canExtractItemFromSlot(inventoryIn, itemstack, index, direction)) { if(itemstack != null && (!(inventoryIn instanceof ISidedInventory) || ((ISidedInventory)inventoryIn).canExtractItem(index))) {
ItemStack itemstack1 = itemstack.copy(); ItemStack itemstack1 = itemstack.copy();
ItemStack itemstack2 = putStackInInventoryAllSlots(this, inventoryIn.decrStackSize(index, 1), (Facing)null); ItemStack itemstack2 = putStackInInventoryAllSlots(this, inventoryIn.decrStackSize(index, 1), null);
if(itemstack2 == null || itemstack2.isEmpty()) { if(itemstack2 == null || itemstack2.isEmpty()) {
inventoryIn.markDirty(); inventoryIn.markDirty();
@ -298,20 +303,12 @@ public class TileEntityItemPipe extends TileEntity implements IInventory, ITicka
return false; return false;
} }
private List<EntityItem> findDroppedItems(BlockPos pos) {
return this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class,
new BoundingBox((double)pos.getX(), (double)pos.getY(), (double)pos.getZ(), (double)pos.getX() + 1.0, (double)pos.getY() + 1.0, (double)pos.getZ() + 1.0), new Predicate<EntityItem>() {
public boolean test(EntityItem entity) {
return entity.isEntityAlive();
}
});
}
protected boolean transferIn() { protected boolean transferIn() {
State state = this.getState(); State state = this.getState();
Facing facing = state.getValue(BlockPipe.FACING); Facing facing = state.getValue(BlockPipe.FACING);
for(Facing dir : Facing.values()) { for(Facing dir : Facing.values()) {
IInventory inv = (this.suck ? dir == facing.getOpposite() : dir != facing) ? this.getInventory(this.pos.offset(dir), false, this.suck) : null; BlockPos pos = this.pos.offset(dir);
IInventory inv = (this.suck ? dir == facing.getOpposite() : dir != facing) ? this.getInventory(pos, false, this.suck) : null;
if(inv != null) { if(inv != null) {
Facing opposite = dir.getOpposite(); Facing opposite = dir.getOpposite();
@ -320,13 +317,10 @@ public class TileEntityItemPipe extends TileEntity implements IInventory, ITicka
} }
if(inv instanceof ISidedInventory sided) { if(inv instanceof ISidedInventory sided) {
int[] slots = sided.getSlotsForFace(opposite); int slot = sided.getSlotForFace(opposite);
for(int i = 0; i < slots.length; ++i) { if(slot >= 0 && this.pullItemFromSlot(inv, slot, opposite))
if(this.pullItemFromSlot(inv, slots[i], opposite)) { return true;
return true;
}
}
} }
else { else {
int size = inv.getSizeInventory(); int size = inv.getSizeInventory();
@ -339,8 +333,13 @@ public class TileEntityItemPipe extends TileEntity implements IInventory, ITicka
} }
} }
else if(this.suck && dir == facing.getOpposite()) { else if(this.suck && dir == facing.getOpposite()) {
for(EntityItem entity : this.findDroppedItems(this.pos.offset(dir))) { for(EntityItem entity : this.world.<EntityItem>getEntitiesWithinAABB(EntityItem.class,
if(putDropInInventoryAllSlots(this, entity)) { new BoundingBox((double)pos.getX(), (double)pos.getY(), (double)pos.getZ(), (double)pos.getX() + 1.0, (double)pos.getY() + 1.0, (double)pos.getZ() + 1.0), new Predicate<EntityItem>() {
public boolean test(EntityItem entity) {
return entity.isEntityAlive();
}
})) {
if(insertDrop(entity)) {
return true; return true;
} }
} }
@ -352,30 +351,22 @@ public class TileEntityItemPipe extends TileEntity implements IInventory, ITicka
// common // common
private static boolean canInsertItemInSlot(IInventory inventoryIn, ItemStack stack, int index, Facing side) { private static ItemStack insertStack(IInventory inventoryIn, ItemStack add, int index) {
return !inventoryIn.isItemValidForSlot(index, stack) ? false : !(inventoryIn instanceof ISidedInventory) || ((ISidedInventory)inventoryIn).canInsertItem(index, stack, side); ItemStack current = inventoryIn.getStackInSlot(index);
}
private static boolean canCombine(ItemStack stack1, ItemStack stack2) { if(inventoryIn.isItemValidForSlot(index, add) && (!(inventoryIn instanceof ISidedInventory) || ((ISidedInventory)inventoryIn).canInsertItem(index, add))) {
return stack1.getItem() != stack2.getItem() ? false : (stack1.isOverLimit() ? false : ItemStack.dataEquals(stack1, stack2));
}
private static ItemStack insertStack(IInventory inventoryIn, ItemStack stack, int index, Facing side) {
ItemStack itemstack = inventoryIn.getStackInSlot(index);
if(canInsertItemInSlot(inventoryIn, stack, index, side)) {
boolean flag = false; boolean flag = false;
if(itemstack == null) { if(current == null) {
inventoryIn.setInventorySlotContents(index, stack); inventoryIn.setInventorySlotContents(index, add);
stack = null; add = null;
flag = true; flag = true;
} }
else if(canCombine(itemstack, stack)) { else if(current.getItem() == add.getItem() && !current.isOverLimit() && ItemStack.dataEquals(current, add)) {
int i = stack.getMaxStackSize() - itemstack.getSize(); int i = add.getMaxStackSize() - current.getSize();
int j = Math.min(stack.getSize(), i); int j = Math.min(add.getSize(), i);
stack.decrSize(j); add.decrSize(j);
itemstack.incrSize(j); current.incrSize(j);
flag = j > 0; flag = j > 0;
} }
@ -394,23 +385,23 @@ public class TileEntityItemPipe extends TileEntity implements IInventory, ITicka
} }
} }
return stack; return add;
} }
private static ItemStack putStackInInventoryAllSlots(IInventory inventoryIn, ItemStack stack, Facing side) { private static ItemStack putStackInInventoryAllSlots(IInventory inventoryIn, ItemStack stack, Facing side) {
if(inventoryIn instanceof ISidedInventory && side != null) { if(inventoryIn instanceof ISidedInventory sided) {
ISidedInventory isidedinventory = (ISidedInventory)inventoryIn; if(side != null) {
int[] aint = isidedinventory.getSlotsForFace(side); int slot = sided.getSlotForFace(side);
for(int k = 0; k < aint.length && stack != null && !stack.isEmpty(); ++k) { if(slot >= 0 && stack != null && !stack.isEmpty())
stack = insertStack(inventoryIn, stack, aint[k], side); stack = insertStack(inventoryIn, stack, slot);
} }
} }
else { else {
int i = inventoryIn.getSizeInventory(); int i = inventoryIn.getSizeInventory();
for(int j = 0; j < i && stack != null && !stack.isEmpty(); ++j) { for(int j = 0; j < i && stack != null && !stack.isEmpty(); ++j) {
stack = insertStack(inventoryIn, stack, j, side); stack = insertStack(inventoryIn, stack, j);
} }
} }
@ -421,30 +412,29 @@ public class TileEntityItemPipe extends TileEntity implements IInventory, ITicka
return stack; return stack;
} }
private IInventory getEntityInventory(BlockPos pos) { private IInventory getInventory(BlockPos pos, boolean pipe, boolean suck) {
List<Entity> list = this.world.getEntitiesInAABBexcluding((Entity)null,
new BoundingBox(this.getXPos() - 0.5D, this.getYPos() - 0.5D, this.getZPos() - 0.5D, this.getXPos() + 0.5D, this.getYPos() + 0.5D, this.getZPos() + 0.5D), new Predicate<Entity>() {
public boolean test(Entity entity) {
return entity instanceof IInventory && !(entity instanceof EntityLiving) && entity.isEntityAlive();
}
});
return list.size() > 0 ? (IInventory)list.get(this.world.rand.zrange(list.size())) : null;
}
private IInventory getInventory(BlockPos blockpos, boolean pipe, boolean suck) {
IInventory inv = null; IInventory inv = null;
Block block = this.world.getState(blockpos).getBlock(); Block block = this.world.getState(pos).getBlock();
if(block instanceof ITileEntityProvider) { if(block instanceof ITileEntityProvider) {
TileEntity te = this.world.getTileEntity(blockpos); TileEntity te = this.world.getTileEntity(pos);
if(te instanceof IInventory && (pipe || !(te instanceof TileEntityItemPipe))) { if(te instanceof IInventory && (pipe || !(te instanceof TileEntityItemPipe))) {
inv = (IInventory)te; inv = (IInventory)te;
if(inv instanceof TileEntityChest && block instanceof BlockChest) { if(inv instanceof TileEntityChest && block instanceof BlockChest) {
inv = ((BlockChest)block).getChest(this.world, blockpos); inv = ((BlockChest)block).getChest(this.world, pos);
} }
} }
} }
return inv == null && suck ? this.getEntityInventory(blockpos) : inv; if(inv == null && suck) {
List<Entity> list = this.world.getEntitiesInAABBexcluding((Entity)null,
new BoundingBox(this.getXPos() - 0.5D, this.getYPos() - 0.5D, this.getZPos() - 0.5D, this.getXPos() + 0.5D, this.getYPos() + 0.5D, this.getZPos() + 0.5D), new Predicate<Entity>() {
public boolean test(Entity entity) {
return entity instanceof IInventory && !(entity instanceof EntityLiving) && entity.isEntityAlive();
}
});
return list.size() > 0 ? (IInventory)list.get(this.world.rand.zrange(list.size())) : null;
}
return inv;
} }
} }

View file

@ -193,6 +193,8 @@ public abstract class Vars {
public static boolean editSigns = true; public static boolean editSigns = true;
@Var(name = "dropPlayerSkulls") @Var(name = "dropPlayerSkulls")
public static boolean skullDrop = true; public static boolean skullDrop = true;
@Var(name = "deviceExplosions")
public static boolean deviceExplosions = true;
@Var(name = "keepInventory") @Var(name = "keepInventory")
public static boolean keepInventory = false; public static boolean keepInventory = false;
@ -249,8 +251,10 @@ public abstract class Vars {
public static int orbDamageOther = 0; public static int orbDamageOther = 0;
@Var(name = "healChance") @Var(name = "healChance")
public static int healChance = 5; public static int healChance = 5;
@Var(name = "pipeCooldown", min = 0, max = 160) @Var(name = "pipeInputCooldown", min = 0, max = 160)
public static int pipeDelay = 2; public static int pipeInDelay = 2;
@Var(name = "pipeOutputCooldown", min = 0, max = 2)
public static int pipeOutDelay = 2;
@Var(name = "dispenserCooldown", min = 0, max = 160) @Var(name = "dispenserCooldown", min = 0, max = 160)
public static int dispenserDelay = 1; public static int dispenserDelay = 1;
@Var(name = "xpCooldown", min = 0, max = 10) @Var(name = "xpCooldown", min = 0, max = 10)