Very unstable improved machine searching

This commit is contained in:
Raoul Van den Berge
2016-05-13 21:32:40 +02:00
parent 2ae904cceb
commit fbb07f82fa
10 changed files with 216 additions and 204 deletions

View File

@@ -8,6 +8,7 @@ import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
@@ -132,6 +133,22 @@ public abstract class BlockBase extends Block {
super.breakBlock(world, pos, state);
}
@Override
public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) {
if (willHarvest) {
return true;
}
return super.removedByPlayer(state, world, pos, player, willHarvest);
}
@Override
public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, TileEntity tile, ItemStack stack) {
super.harvestBlock(world, player, pos, state, tile, stack);
world.setBlockToAir(pos);
}
public Item createItemForBlock() {
return new ItemBlockBase(this, false);
}

View File

@@ -93,22 +93,6 @@ public class BlockController extends BlockBase {
super.breakBlock(world, pos, state);
}
@Override
public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) {
if (willHarvest) {
return true;
}
return super.removedByPlayer(state, world, pos, player, willHarvest);
}
@Override
public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, TileEntity tile, ItemStack stack) {
super.harvestBlock(world, player, pos, state, tile, stack);
world.setBlockToAir(pos);
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack itemStack) {
super.onBlockPlacedBy(world, pos, state, player, itemStack);

View File

@@ -1,11 +1,15 @@
package refinedstorage.block;
import net.minecraft.block.Block;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import refinedstorage.tile.TileMachine;
public abstract class BlockMachine extends BlockBase {
@@ -33,4 +37,39 @@ public abstract class BlockMachine extends BlockBase {
return super.getActualState(state, world, pos)
.withProperty(CONNECTED, ((TileMachine) world.getTileEntity(pos)).isConnected());
}
@Override
public void breakBlock(World world, BlockPos pos, IBlockState state) {
super.breakBlock(world, pos, state);
if (!world.isRemote) {
TileMachine machine = (TileMachine) world.getTileEntity(pos);
if (machine.isConnected()) {
machine.onDisconnected();
}
}
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack stack) {
super.onBlockPlacedBy(world, pos, state, player, stack);
if (!world.isRemote) {
((TileMachine) world.getTileEntity(pos)).searchController();
}
}
@Override
public void onNeighborBlockChange(World world, BlockPos pos, IBlockState state, Block neighborBlock) {
super.onNeighborBlockChange(world, pos, state, neighborBlock);
if (!world.isRemote) {
TileMachine machine = (TileMachine) world.getTileEntity(pos);
if (!machine.isConnected()) {
machine.searchController();
}
}
}
}

View File

@@ -47,7 +47,7 @@ public class MessageWirelessGridCraftingStart extends MessageHandlerPlayerToServ
public void handle(MessageWirelessGridCraftingStart message, EntityPlayerMP player) {
TileEntity tile = player.worldObj.getTileEntity(new BlockPos(message.controllerX, message.controllerY, message.controllerZ));
if (tile instanceof TileController && ((TileController) tile).isActive()) {
if (tile instanceof TileController && ((TileController) tile).canRun()) {
((TileController) tile).onCraftingRequested(message.id, message.quantity);
}
}

View File

@@ -47,7 +47,7 @@ public class MessageWirelessGridStoragePull extends MessageHandlerPlayerToServer
public void handle(MessageWirelessGridStoragePull message, EntityPlayerMP player) {
TileEntity tile = player.worldObj.getTileEntity(new BlockPos(message.controllerX, message.controllerY, message.controllerZ));
if (tile instanceof TileController && ((TileController) tile).isActive()) {
if (tile instanceof TileController && ((TileController) tile).canRun()) {
((TileController) tile).handleStoragePull(message.id, message.flags, player);
}
}

View File

@@ -47,7 +47,7 @@ public class MessageWirelessGridStoragePush extends MessageHandlerPlayerToServer
public void handle(MessageWirelessGridStoragePush message, EntityPlayerMP player) {
TileEntity tile = player.worldObj.getTileEntity(new BlockPos(message.controllerX, message.controllerY, message.controllerZ));
if (tile instanceof TileController && ((TileController) tile).isActive()) {
if (tile instanceof TileController && ((TileController) tile).canRun()) {
((TileController) tile).handleStoragePush(message.playerSlot, message.one, player);
}
}

View File

@@ -0,0 +1,40 @@
package refinedstorage.tile;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import refinedstorage.RefinedStorageBlocks;
import java.util.Set;
public class ControllerSearcher {
public static TileController search(World world, BlockPos current, Set<String> visited) {
if (visited.contains(current.getX() + "," + current.getY() + "," + current.getZ())) {
return null;
}
visited.add(current.getX() + "," + current.getY() + "," + current.getZ());
TileEntity tile = world.getTileEntity(current);
if (tile instanceof TileController) {
return (TileController) tile;
}
Block block = world.getBlockState(current).getBlock();
if (tile instanceof TileMachine || block == RefinedStorageBlocks.CABLE) {
for (EnumFacing dir : EnumFacing.VALUES) {
TileController controller = search(world, current.offset(dir), visited);
if (controller != null) {
return controller;
}
}
}
return null;
}
}

View File

@@ -1,46 +0,0 @@
package refinedstorage.tile;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import refinedstorage.RefinedStorageBlocks;
import java.util.List;
import java.util.Set;
public class MachineSearcher {
public static void search(TileController controller, BlockPos current, Set<String> visited, List<TileMachine> machines) {
if (visited.contains(current.getX() + "," + current.getY() + "," + current.getZ()) || controller.getPos().equals(current)) {
return;
}
visited.add(current.getX() + "," + current.getY() + "," + current.getZ());
Block block = controller.getWorld().getBlockState(current).getBlock();
TileEntity tile = controller.getWorld().getTileEntity(current);
if (tile instanceof TileController) {
if (!tile.getPos().equals(controller.getPos())) {
controller.getWorld().createExplosion(null, tile.getPos().getX(), tile.getPos().getY(), tile.getPos().getZ(), 4.5f, true);
}
}
if (tile instanceof TileMachine) {
TileMachine machine = (TileMachine) tile;
if (machine.getRedstoneMode().isEnabled(controller.getWorld(), tile.getPos())) {
machines.add(machine);
} else if (machine instanceof TileRelay) {
// If the relay is disabled we can't search any further
return;
}
}
if (tile instanceof TileMachine || block == RefinedStorageBlocks.CABLE) {
for (EnumFacing dir : EnumFacing.VALUES) {
search(controller, current.offset(dir), visited, machines);
}
}
}
}

View File

@@ -10,7 +10,6 @@ import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
@@ -54,11 +53,14 @@ public class TileController extends TileBase implements IEnergyReceiver, INetwor
private List<ItemGroup> itemGroups = new ArrayList<ItemGroup>();
private List<IStorage> storages = new ArrayList<IStorage>();
private List<WirelessGridConsumer> wirelessGridConsumers = new ArrayList<WirelessGridConsumer>();
private List<WirelessGridConsumer> wirelessGridConsumersMarkedForRemoval = new ArrayList<WirelessGridConsumer>();
private List<WirelessGridConsumer> wirelessGridConsumersToRemove = new ArrayList<WirelessGridConsumer>();
private RedstoneMode redstoneMode = RedstoneMode.IGNORE;
private List<TileMachine> machines = new ArrayList<TileMachine>();
private List<TileMachine> machinesToAdd = new ArrayList<TileMachine>();
private List<TileMachine> machinesToRemove = new ArrayList<TileMachine>();
private List<ClientSideMachine> clientSideMachines = new ArrayList<ClientSideMachine>();
private List<CraftingPattern> patterns = new ArrayList<CraftingPattern>();
@@ -66,120 +68,95 @@ public class TileController extends TileBase implements IEnergyReceiver, INetwor
private List<ICraftingTask> craftingTasksToAdd = new ArrayList<ICraftingTask>();
private List<ICraftingTask> craftingTasksToCancel = new ArrayList<ICraftingTask>();
private Set<String> visited = new HashSet<String>();
private EnergyStorage energy = new EnergyStorage(ENERGY_CAPACITY);
private int energyUsage;
private int wirelessGridRange;
private boolean destroyed = false;
private long lastEnergyRender;
private boolean machinesHavePosition(List<TileMachine> machines, BlockPos pos) {
for (TileEntity machine : machines) {
if (machine.getPos().getX() == pos.getX() && machine.getPos().getY() == pos.getY() && machine.getPos().getZ() == pos.getZ()) {
return true;
}
}
public void addMachine(TileMachine machine) {
machinesToAdd.add(machine);
}
return false;
public void removeMachine(TileMachine machine) {
machinesToRemove.add(machine);
}
@Override
public void update() {
super.update();
if (!worldObj.isRemote && !destroyed) {
if (!worldObj.isRemote) {
if (!canRun()) {
disconnectAll();
}
machines.addAll(machinesToAdd);
machinesToAdd.clear();
machines.removeAll(machinesToRemove);
machinesToRemove.clear();
int lastEnergy = energy.getEnergyStored();
if (ticks % 20 == 0) {
if (!isActive()) {
disconnectAll();
} else {
visited.clear();
int newWirelessGridRange = 0;
int newEnergyUsage = 10;
List<IStorage> newStorages = new ArrayList<IStorage>();
List<CraftingPattern> newPatterns = new ArrayList<CraftingPattern>();
List<TileMachine> newMachines = new ArrayList<TileMachine>();
for (TileMachine machine : machines) {
machine.updateMachine();
for (EnumFacing dir : EnumFacing.VALUES) {
MachineSearcher.search(this, pos.offset(dir), visited, newMachines);
}
for (TileMachine machine : machines) {
if (!machinesHavePosition(newMachines, machine.getPos())) {
machine.onDisconnected();
}
}
int newWirelessGridRange = 0;
int newEnergyUsage = 0;
List<IStorage> newStorages = new ArrayList<IStorage>();
List<CraftingPattern> newPatterns = new ArrayList<CraftingPattern>();
for (TileMachine machine : newMachines) {
if (machine instanceof TileWirelessTransmitter) {
newWirelessGridRange += ((TileWirelessTransmitter) machine).getRange();
}
if (machine instanceof IStorageProvider) {
((IStorageProvider) machine).provide(newStorages);
}
if (machine instanceof TileCrafter) {
TileCrafter crafter = (TileCrafter) machine;
for (int i = 0; i < TileCrafter.PATTERN_SLOTS; ++i) {
if (crafter.getStackInSlot(i) != null) {
ItemStack pattern = crafter.getStackInSlot(i);
newPatterns.add(new CraftingPattern(
crafter.getPos().getX(),
crafter.getPos().getY(),
crafter.getPos().getZ(),
ItemPattern.isProcessing(pattern),
ItemPattern.getInputs(pattern),
ItemPattern.getOutputs(pattern)));
}
}
}
newEnergyUsage += machine.getEnergyUsage();
if (!machinesHavePosition(machines, machine.getPos())) {
machine.onConnected(this);
} else {
/* This machine is in our machine list, but due to a chunk reload the tile entity
would get reset which causes its connected property to reset too (to false).
So, if the machine is in our list but not connected (which is the case due to a TE reload)
we connect it either way. */
if (!machine.isConnected()) {
machine.onConnected(this);
}
}
}
wirelessGridRange = newWirelessGridRange;
energyUsage = newEnergyUsage;
machines = newMachines;
storages = newStorages;
patterns = newPatterns;
Collections.sort(storages, new Comparator<IStorage>() {
@Override
public int compare(IStorage s1, IStorage s2) {
if (s1.getPriority() == s2.getPriority()) {
return 0;
}
return (s1.getPriority() > s2.getPriority()) ? -1 : 1;
}
});
syncItems();
if (machine instanceof TileWirelessTransmitter) {
newWirelessGridRange += ((TileWirelessTransmitter) machine).getRange();
}
if (machine instanceof IStorageProvider) {
((IStorageProvider) machine).provide(newStorages);
}
if (machine instanceof TileCrafter) {
TileCrafter crafter = (TileCrafter) machine;
for (int i = 0; i < TileCrafter.PATTERN_SLOTS; ++i) {
if (crafter.getStackInSlot(i) == null) {
continue;
}
ItemStack pattern = crafter.getStackInSlot(i);
newPatterns.add(new CraftingPattern(
crafter.getPos().getX(),
crafter.getPos().getY(),
crafter.getPos().getZ(),
ItemPattern.isProcessing(pattern),
ItemPattern.getInputs(pattern),
ItemPattern.getOutputs(pattern)));
}
}
newEnergyUsage += machine.getEnergyUsage();
}
wirelessGridRange = newWirelessGridRange;
energyUsage = newEnergyUsage;
storages = newStorages;
patterns = newPatterns;
Collections.sort(storages, new Comparator<IStorage>() {
@Override
public int compare(IStorage s1, IStorage s2) {
if (s1.getPriority() == s2.getPriority()) {
return 0;
}
return (s1.getPriority() > s2.getPriority()) ? -1 : 1;
}
});
syncItems();
for (ICraftingTask taskToCancel : craftingTasksToCancel) {
taskToCancel.onCancelled(this);
}
@@ -202,7 +179,7 @@ public class TileController extends TileBase implements IEnergyReceiver, INetwor
}
}
if (isActive()) {
if (canRun()) {
switch (getType()) {
case NORMAL:
energy.extractEnergy(energyUsage, false);
@@ -213,8 +190,8 @@ public class TileController extends TileBase implements IEnergyReceiver, INetwor
}
}
wirelessGridConsumers.removeAll(wirelessGridConsumersMarkedForRemoval);
wirelessGridConsumersMarkedForRemoval.clear();
wirelessGridConsumers.removeAll(wirelessGridConsumersToRemove);
wirelessGridConsumersToRemove.clear();
Iterator<WirelessGridConsumer> gridConsumerIterator = wirelessGridConsumers.iterator();
@@ -224,7 +201,7 @@ public class TileController extends TileBase implements IEnergyReceiver, INetwor
if (!RefinedStorageUtils.compareStack(consumer.getWirelessGrid(), consumer.getPlayer().getHeldItem(consumer.getHand()))) {
consumer.getPlayer().closeScreen(); // This will call onContainerClosed on the Container and remove it from the list
} else {
if (isActive()) {
if (canRun()) {
RefinedStorage.NETWORK.sendTo(new MessageWirelessGridItems(this), (EntityPlayerMP) consumer.getPlayer());
}
}
@@ -250,8 +227,6 @@ public class TileController extends TileBase implements IEnergyReceiver, INetwor
public void onDestroyed() {
disconnectAll();
destroyed = true;
}
private void disconnectAll() {
@@ -448,7 +423,7 @@ public class TileController extends TileBase implements IEnergyReceiver, INetwor
WirelessGridConsumer consumer = getWirelessGridConsumer(player);
if (consumer != null) {
wirelessGridConsumersMarkedForRemoval.add(consumer);
wirelessGridConsumersToRemove.add(consumer);
}
}
@@ -555,7 +530,7 @@ public class TileController extends TileBase implements IEnergyReceiver, INetwor
return true;
}
public boolean isActive() {
public boolean canRun() {
return energy.getEnergyStored() >= getEnergyUsage() && redstoneMode.isEnabled(worldObj, pos);
}
@@ -632,7 +607,7 @@ public class TileController extends TileBase implements IEnergyReceiver, INetwor
@Override
public void sendContainerData(ByteBuf buf) {
buf.writeInt(isActive() ? energyUsage : 0);
buf.writeInt(canRun() ? energyUsage : 0);
buf.writeInt(redstoneMode.id);

View File

@@ -1,62 +1,65 @@
package refinedstorage.tile;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.Block;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import refinedstorage.block.BlockMachine;
import refinedstorage.tile.config.IRedstoneModeConfig;
import refinedstorage.tile.config.RedstoneMode;
import java.util.HashSet;
import java.util.Set;
public abstract class TileMachine extends TileBase implements INetworkTile, IRedstoneModeConfig {
protected boolean connected = false;
protected RedstoneMode redstoneMode = RedstoneMode.IGNORE;
protected TileController controller;
private Block machineBlock;
public void onConnected(TileController controller) {
if (worldObj != null && worldObj.getBlockState(pos).getBlock() == machineBlock) {
markDirty();
this.connected = true;
this.controller = controller;
worldObj.setBlockState(pos, worldObj.getBlockState(pos).withProperty(BlockMachine.CONNECTED, true));
}
}
public void onDisconnected() {
if (worldObj != null && worldObj.getBlockState(pos).getBlock() == machineBlock) {
markDirty();
this.connected = false;
this.controller = null;
worldObj.setBlockState(pos, worldObj.getBlockState(pos).withProperty(BlockMachine.CONNECTED, false));
}
}
private Set<String> visited = new HashSet<String>();
public TileController getController() {
return controller;
}
public void searchController() {
visited.clear();
TileController newController = ControllerSearcher.search(worldObj, pos, visited);
if (newController != null) {
this.controller = newController;
onConnected();
} else if (this.controller != null) {
this.controller = null;
onDisconnected();
}
}
@Override
public void update() {
if (worldObj == null) {
super.update();
return;
}
public void onLoad() {
super.onLoad();
if (ticks == 0) {
machineBlock = worldObj.getBlockState(pos).getBlock();
if (!worldObj.isRemote && !connected) {
searchController();
}
}
super.update();
public void onConnected() {
connected = true;
if (!worldObj.isRemote && isConnected()) {
updateMachine();
}
worldObj.setBlockState(pos, worldObj.getBlockState(pos).withProperty(BlockMachine.CONNECTED, true));
controller.addMachine(this);
}
public void onDisconnected() {
connected = false;
worldObj.setBlockState(pos, worldObj.getBlockState(pos).withProperty(BlockMachine.CONNECTED, false));
controller.removeMachine(this);
}
public boolean isConnected() {