Decouple INetwork from ControllerTile
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
package com.raoulvdberge.refinedstorage;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.network.NetworkType;
|
||||
import com.raoulvdberge.refinedstorage.api.network.grid.GridType;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.StorageType;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.NetworkListener;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.NetworkNodeListener;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.factory.GridBlockGridFactory;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.*;
|
||||
@@ -89,6 +91,7 @@ public final class RS {
|
||||
NetworkNodeProxyCapability.register();
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(new NetworkNodeListener());
|
||||
MinecraftForge.EVENT_BUS.register(new NetworkListener());
|
||||
|
||||
API.instance().getStorageDiskRegistry().add(ItemStorageDiskFactory.ID, new ItemStorageDiskFactory());
|
||||
API.instance().getStorageDiskRegistry().add(FluidStorageDiskFactory.ID, new FluidStorageDiskFactory());
|
||||
@@ -140,8 +143,8 @@ public final class RS {
|
||||
@SubscribeEvent
|
||||
public void onRegisterBlocks(RegistryEvent.Register<Block> e) {
|
||||
e.getRegistry().register(new QuartzEnrichedIronBlock());
|
||||
e.getRegistry().register(new ControllerBlock(ControllerBlock.Type.NORMAL));
|
||||
e.getRegistry().register(new ControllerBlock(ControllerBlock.Type.CREATIVE));
|
||||
e.getRegistry().register(new ControllerBlock(NetworkType.NORMAL));
|
||||
e.getRegistry().register(new ControllerBlock(NetworkType.CREATIVE));
|
||||
e.getRegistry().register(new MachineCasingBlock());
|
||||
e.getRegistry().register(new CableBlock());
|
||||
e.getRegistry().register(new DiskDriveBlock());
|
||||
@@ -167,8 +170,8 @@ public final class RS {
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRegisterTiles(RegistryEvent.Register<TileEntityType<?>> e) {
|
||||
e.getRegistry().register(registerTileDataParameters(TileEntityType.Builder.create(() -> new ControllerTile(ControllerBlock.Type.NORMAL), RSBlocks.CONTROLLER).build(null).setRegistryName(RS.ID, "controller")));
|
||||
e.getRegistry().register(registerTileDataParameters(TileEntityType.Builder.create(() -> new ControllerTile(ControllerBlock.Type.CREATIVE), RSBlocks.CREATIVE_CONTROLLER).build(null).setRegistryName(RS.ID, "creative_controller")));
|
||||
e.getRegistry().register(registerTileDataParameters(TileEntityType.Builder.create(() -> new ControllerTile(NetworkType.NORMAL), RSBlocks.CONTROLLER).build(null).setRegistryName(RS.ID, "controller")));
|
||||
e.getRegistry().register(registerTileDataParameters(TileEntityType.Builder.create(() -> new ControllerTile(NetworkType.CREATIVE), RSBlocks.CREATIVE_CONTROLLER).build(null).setRegistryName(RS.ID, "creative_controller")));
|
||||
e.getRegistry().register(TileEntityType.Builder.create(CableTile::new, RSBlocks.CABLE).build(null).setRegistryName(RS.ID, "cable"));
|
||||
e.getRegistry().register(registerTileDataParameters(TileEntityType.Builder.create(DiskDriveTile::new, RSBlocks.DISK_DRIVE).build(null).setRegistryName(RS.ID, "disk_drive")));
|
||||
e.getRegistry().register(registerTileDataParameters(TileEntityType.Builder.create(() -> new GridTile(GridType.NORMAL), RSBlocks.GRID).build(null).setRegistryName(RS.ID, "grid")));
|
||||
|
@@ -7,6 +7,7 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreview
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingRequestInfo;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetworkManager;
|
||||
import com.raoulvdberge.refinedstorage.api.network.grid.ICraftingGridBehavior;
|
||||
import com.raoulvdberge.refinedstorage.api.network.grid.IGridManager;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
@@ -23,8 +24,6 @@ import com.raoulvdberge.refinedstorage.api.util.IQuantityFormatter;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
@@ -63,6 +62,14 @@ public interface IRSAPI {
|
||||
*/
|
||||
INetworkNodeManager getNetworkNodeManager(ServerWorld world);
|
||||
|
||||
/**
|
||||
* Gets a network manager for a given world.
|
||||
*
|
||||
* @param world world
|
||||
* @return the network manager for a given world
|
||||
*/
|
||||
INetworkManager getNetworkManager(ServerWorld world);
|
||||
|
||||
/**
|
||||
* @return the crafting task registry
|
||||
*/
|
||||
@@ -194,14 +201,6 @@ public interface IRSAPI {
|
||||
*/
|
||||
List<ICraftingPatternRenderHandler> getPatternRenderHandlers();
|
||||
|
||||
/**
|
||||
* Notifies the neighbors of a node that there is a node placed at the given position.
|
||||
*
|
||||
* @param world the world
|
||||
* @param pos the position of the node
|
||||
*/
|
||||
void discoverNode(IWorld world, BlockPos pos);
|
||||
|
||||
/**
|
||||
* @param stack the stack
|
||||
* @return a hashcode for the given stack
|
||||
|
@@ -11,15 +11,17 @@ import com.raoulvdberge.refinedstorage.api.storage.tracker.IStorageTracker;
|
||||
import com.raoulvdberge.refinedstorage.api.util.Action;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.energy.IEnergyStorage;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Represents a network, usually is a controller.
|
||||
* Represents a network.
|
||||
*/
|
||||
public interface INetwork {
|
||||
/**
|
||||
@@ -28,15 +30,30 @@ public interface INetwork {
|
||||
int getEnergyUsage();
|
||||
|
||||
/**
|
||||
* @return the position of this network in the world
|
||||
* @return the energy storage
|
||||
*/
|
||||
BlockPos getPosition();
|
||||
IEnergyStorage getEnergyStorage();
|
||||
|
||||
/**
|
||||
* @return the network type
|
||||
*/
|
||||
NetworkType getType();
|
||||
|
||||
/**
|
||||
* @return true if this network is able to run (usually corresponds to the redstone configuration), false otherwise
|
||||
*/
|
||||
boolean canRun();
|
||||
|
||||
/**
|
||||
* Updates the network.
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Called when the network is removed.
|
||||
*/
|
||||
void onRemoved();
|
||||
|
||||
/**
|
||||
* @return a graph of connected nodes to this network
|
||||
*/
|
||||
@@ -227,5 +244,26 @@ public interface INetwork {
|
||||
/**
|
||||
* @return the world where this network is in
|
||||
*/
|
||||
World world();
|
||||
World getWorld();
|
||||
|
||||
/**
|
||||
* @return the position of this network in the world
|
||||
*/
|
||||
BlockPos getPosition();
|
||||
|
||||
/**
|
||||
* @return a read network
|
||||
*/
|
||||
INetwork readFromNbt(CompoundNBT tag);
|
||||
|
||||
/**
|
||||
* @param tag the tag to write to
|
||||
* @return a written tag
|
||||
*/
|
||||
CompoundNBT writeToNbt(CompoundNBT tag);
|
||||
|
||||
/**
|
||||
* Marks the network dirty.
|
||||
*/
|
||||
void markDirty();
|
||||
}
|
||||
|
@@ -0,0 +1,45 @@
|
||||
package com.raoulvdberge.refinedstorage.api.network;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* This is a registry for network nodes in the world.
|
||||
*/
|
||||
public interface INetworkManager {
|
||||
/**
|
||||
* Gets a network from the registry at a given position.
|
||||
*
|
||||
* @param pos the position of the network
|
||||
* @return the network at the given position, or null if no network was found
|
||||
*/
|
||||
@Nullable
|
||||
INetwork getNetwork(BlockPos pos);
|
||||
|
||||
/**
|
||||
* Removes a network from the registry at a given position.
|
||||
*
|
||||
* @param pos the position of the network
|
||||
*/
|
||||
void removeNetwork(BlockPos pos);
|
||||
|
||||
/**
|
||||
* Sets a network in the registry at a given position.
|
||||
*
|
||||
* @param pos the position of the network
|
||||
* @param node the node
|
||||
*/
|
||||
void setNetwork(BlockPos pos, INetwork node);
|
||||
|
||||
/**
|
||||
* @return all networks in this registry
|
||||
*/
|
||||
Collection<INetwork> all();
|
||||
|
||||
/**
|
||||
* Marks the network manager for saving.
|
||||
*/
|
||||
void markForSaving();
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
package com.raoulvdberge.refinedstorage.api.network;
|
||||
|
||||
/**
|
||||
* Represents a network type.
|
||||
*/
|
||||
public enum NetworkType {
|
||||
/**
|
||||
* A normal network.
|
||||
*/
|
||||
NORMAL,
|
||||
/**
|
||||
* A creative network.
|
||||
*/
|
||||
CREATIVE
|
||||
}
|
@@ -8,11 +8,11 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreview
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingRequestInfo;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetworkManager;
|
||||
import com.raoulvdberge.refinedstorage.api.network.grid.ICraftingGridBehavior;
|
||||
import com.raoulvdberge.refinedstorage.api.network.grid.IGridManager;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeManager;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeRegistry;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.StorageType;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDisk;
|
||||
@@ -20,7 +20,6 @@ import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskManager;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskRegistry;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.disk.IStorageDiskSync;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorageProvider;
|
||||
import com.raoulvdberge.refinedstorage.api.util.Action;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IQuantityFormatter;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
@@ -29,6 +28,7 @@ import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.Craf
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementRegistry;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementRegistry;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry.CraftingTaskRegistry;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.NetworkManager;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.NetworkNodeManager;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.NetworkNodeRegistry;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.CraftingGridBehavior;
|
||||
@@ -38,15 +38,10 @@ import com.raoulvdberge.refinedstorage.apiimpl.util.Comparer;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.util.FluidStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.util.ItemStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.util.QuantityFormatter;
|
||||
import com.raoulvdberge.refinedstorage.capability.NetworkNodeProxyCapability;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.INBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
@@ -118,6 +113,13 @@ public class API implements IRSAPI {
|
||||
return world.getSavedData().getOrCreate(() -> new NetworkNodeManager(name, world), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public INetworkManager getNetworkManager(ServerWorld world) {
|
||||
String name = world.getDimension().getType().getRegistryName().getNamespace() + "_" + world.getDimension().getType().getRegistryName().getPath() + "_" + NetworkManager.NAME;
|
||||
|
||||
return world.getSavedData().getOrCreate(() -> new NetworkManager(name, world), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ICraftingTaskRegistry getCraftingTaskRegistry() {
|
||||
@@ -235,26 +237,6 @@ public class API implements IRSAPI {
|
||||
return patternRenderHandlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void discoverNode(IWorld world, BlockPos pos) {
|
||||
for (Direction facing : Direction.values()) {
|
||||
TileEntity tile = world.getTileEntity(pos.offset(facing));
|
||||
|
||||
if (tile != null) {
|
||||
INetworkNodeProxy proxy = tile.getCapability(NetworkNodeProxyCapability.NETWORK_NODE_PROXY_CAPABILITY, facing.getOpposite()).orElse(null);
|
||||
if (proxy != null) {
|
||||
INetworkNode node = proxy.getNode();
|
||||
|
||||
if (node.getNetwork() != null) {
|
||||
node.getNetwork().getNodeGraph().invalidate(Action.PERFORM, node.getNetwork().world(), node.getNetwork().getPosition());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove eventually
|
||||
@Override
|
||||
public int getItemStackHashCode(ItemStack stack) {
|
||||
|
@@ -9,10 +9,10 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskFa
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.tile.ControllerTile;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
@@ -31,7 +31,7 @@ public class CraftingManager implements ICraftingManager {
|
||||
private static final String NBT_TASK_TYPE = "Type";
|
||||
private static final String NBT_TASK_DATA = "Task";
|
||||
|
||||
private ControllerTile network;
|
||||
private INetwork network;
|
||||
|
||||
private Map<String, List<IItemHandlerModifiable>> containerInventories = new LinkedHashMap<>();
|
||||
|
||||
@@ -46,7 +46,7 @@ public class CraftingManager implements ICraftingManager {
|
||||
|
||||
private Set<ICraftingMonitorListener> listeners = new HashSet<>();
|
||||
|
||||
public CraftingManager(ControllerTile network) {
|
||||
public CraftingManager(INetwork network) {
|
||||
this.network = network;
|
||||
}
|
||||
|
||||
|
@@ -30,7 +30,7 @@ class Crafting {
|
||||
}
|
||||
|
||||
public Crafting(INetwork network, CompoundNBT tag) throws CraftingTaskReadException {
|
||||
this.pattern = CraftingTask.readPatternFromNbt(tag.getCompound(NBT_PATTERN), network.world());
|
||||
this.pattern = CraftingTask.readPatternFromNbt(tag.getCompound(NBT_PATTERN), network.getWorld());
|
||||
this.toExtract = CraftingTask.readItemStackList(tag.getList(NBT_TO_EXTRACT, Constants.NBT.TAG_COMPOUND));
|
||||
this.root = tag.getBoolean(NBT_ROOT);
|
||||
|
||||
|
@@ -112,7 +112,7 @@ public class CraftingTask implements ICraftingTask {
|
||||
|
||||
this.requested = API.instance().createCraftingRequestInfo(tag.getCompound(NBT_REQUESTED));
|
||||
this.quantity = tag.getInt(NBT_QUANTITY);
|
||||
this.pattern = readPatternFromNbt(tag.getCompound(NBT_PATTERN), network.world());
|
||||
this.pattern = readPatternFromNbt(tag.getCompound(NBT_PATTERN), network.getWorld());
|
||||
this.ticks = tag.getInt(NBT_TICKS);
|
||||
this.id = tag.getUniqueId(NBT_ID);
|
||||
this.executionStarted = tag.getLong(NBT_EXECUTION_STARTED);
|
||||
|
@@ -36,7 +36,7 @@ class Processing {
|
||||
}
|
||||
|
||||
public Processing(INetwork network, CompoundNBT tag) throws CraftingTaskReadException {
|
||||
this.pattern = CraftingTask.readPatternFromNbt(tag.getCompound(NBT_PATTERN), network.world());
|
||||
this.pattern = CraftingTask.readPatternFromNbt(tag.getCompound(NBT_PATTERN), network.getWorld());
|
||||
this.itemsToReceive = CraftingTask.readItemStackList(tag.getList(NBT_ITEMS_TO_RECEIVE, Constants.NBT.TAG_COMPOUND));
|
||||
this.fluidsToReceive = CraftingTask.readFluidStackList(tag.getList(NBT_FLUIDS_TO_RECEIVE, Constants.NBT.TAG_COMPOUND));
|
||||
this.root = tag.getBoolean(NBT_ROOT);
|
||||
|
@@ -0,0 +1,529 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.network;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.RS;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingManager;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetworkNodeGraph;
|
||||
import com.raoulvdberge.refinedstorage.api.network.NetworkType;
|
||||
import com.raoulvdberge.refinedstorage.api.network.grid.handler.IFluidGridHandler;
|
||||
import com.raoulvdberge.refinedstorage.api.network.grid.handler.IItemGridHandler;
|
||||
import com.raoulvdberge.refinedstorage.api.network.item.INetworkItemHandler;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.network.security.ISecurityManager;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.IStorage;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.cache.IStorageCache;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorage;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.tracker.IStorageTracker;
|
||||
import com.raoulvdberge.refinedstorage.api.util.Action;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.CraftingManager;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.FluidGridHandler;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.ItemGridHandler;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.item.NetworkItemHandler;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.RootNetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.security.SecurityManager;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.cache.FluidStorageCache;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.cache.ItemStorageCache;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.tracker.FluidStorageTracker;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.tracker.ItemStorageTracker;
|
||||
import com.raoulvdberge.refinedstorage.block.ControllerBlock;
|
||||
import com.raoulvdberge.refinedstorage.energy.BaseEnergyStorage;
|
||||
import com.raoulvdberge.refinedstorage.tile.config.IRedstoneConfigurable;
|
||||
import com.raoulvdberge.refinedstorage.tile.config.RedstoneMode;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.energy.IEnergyStorage;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class Network implements INetwork, IRedstoneConfigurable {
|
||||
private static final int THROTTLE_INACTIVE_TO_ACTIVE = 20;
|
||||
private static final int THROTTLE_ACTIVE_TO_INACTIVE = 4;
|
||||
|
||||
private static final String NBT_ENERGY = "Energy";
|
||||
private static final String NBT_ITEM_STORAGE_TRACKER = "ItemStorageTracker";
|
||||
private static final String NBT_FLUID_STORAGE_TRACKER = "FluidStorageTracker";
|
||||
|
||||
private final IItemGridHandler itemGridHandler = new ItemGridHandler(this);
|
||||
private final IFluidGridHandler fluidGridHandler = new FluidGridHandler(this);
|
||||
private final INetworkItemHandler networkItemHandler = new NetworkItemHandler(this);
|
||||
private final INetworkNodeGraph nodeGraph = new NetworkNodeGraph(this);
|
||||
private final ICraftingManager craftingManager = new CraftingManager(this);
|
||||
private final ISecurityManager securityManager = new SecurityManager(this);
|
||||
private final IStorageCache<ItemStack> itemStorage = new ItemStorageCache(this);
|
||||
private final ItemStorageTracker itemStorageTracker = new ItemStorageTracker(this::markDirty);
|
||||
private final IStorageCache<FluidStack> fluidStorage = new FluidStorageCache(this);
|
||||
private final FluidStorageTracker fluidStorageTracker = new FluidStorageTracker(this::markDirty);
|
||||
private final BaseEnergyStorage energy = new BaseEnergyStorage(RS.SERVER_CONFIG.getController().getCapacity(), RS.SERVER_CONFIG.getController().getMaxTransfer());
|
||||
private final RootNetworkNode root;
|
||||
|
||||
private final BlockPos pos;
|
||||
private final World world;
|
||||
private final NetworkType type;
|
||||
private ControllerBlock.EnergyType lastEnergyType = ControllerBlock.EnergyType.OFF;
|
||||
private RedstoneMode redstoneMode = RedstoneMode.IGNORE;
|
||||
|
||||
private boolean throttlingDisabled = true; // Will be enabled after first update
|
||||
private boolean couldRun;
|
||||
private int ticksSinceUpdateChanged;
|
||||
|
||||
public Network(World world, BlockPos pos, NetworkType type) {
|
||||
this.pos = pos;
|
||||
this.world = world;
|
||||
this.type = type;
|
||||
this.root = new RootNetworkNode(this, world, pos);
|
||||
}
|
||||
|
||||
public RootNetworkNode getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public BaseEnergyStorage getEnergy() {
|
||||
return energy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPosition() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRun() {
|
||||
return this.energy.getEnergyStored() > 0 && redstoneMode.isEnabled(world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public INetworkNodeGraph getNodeGraph() {
|
||||
return nodeGraph;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISecurityManager getSecurityManager() {
|
||||
return securityManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICraftingManager getCraftingManager() {
|
||||
return craftingManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
if (!world.isRemote) {
|
||||
if (canRun()) {
|
||||
craftingManager.update();
|
||||
|
||||
if (!craftingManager.getTasks().isEmpty()) {
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
if (type == NetworkType.NORMAL) {
|
||||
if (!RS.SERVER_CONFIG.getController().getUseEnergy()) {
|
||||
this.energy.setStored(this.energy.getMaxEnergyStored());
|
||||
} else if (this.energy.extractEnergy(getEnergyUsage(), true) >= 0) {
|
||||
this.energy.extractEnergy(getEnergyUsage(), false);
|
||||
} else {
|
||||
this.energy.setStored(0);
|
||||
}
|
||||
} else if (type == NetworkType.CREATIVE) {
|
||||
this.energy.setStored(this.energy.getMaxEnergyStored());
|
||||
}
|
||||
|
||||
boolean canRun = canRun();
|
||||
|
||||
if (couldRun != canRun) {
|
||||
++ticksSinceUpdateChanged;
|
||||
|
||||
if ((canRun ? (ticksSinceUpdateChanged > THROTTLE_INACTIVE_TO_ACTIVE) : (ticksSinceUpdateChanged > THROTTLE_ACTIVE_TO_INACTIVE)) || throttlingDisabled) {
|
||||
ticksSinceUpdateChanged = 0;
|
||||
couldRun = canRun;
|
||||
throttlingDisabled = false;
|
||||
|
||||
nodeGraph.invalidate(Action.PERFORM, world, pos);
|
||||
securityManager.invalidate();
|
||||
}
|
||||
} else {
|
||||
ticksSinceUpdateChanged = 0;
|
||||
}
|
||||
|
||||
ControllerBlock.EnergyType energyType = getEnergyType();
|
||||
|
||||
if (lastEnergyType != energyType) {
|
||||
lastEnergyType = energyType;
|
||||
|
||||
world.setBlockState(pos, world.getBlockState(pos).with(ControllerBlock.ENERGY_TYPE, energyType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemGridHandler getItemGridHandler() {
|
||||
return itemGridHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidGridHandler getFluidGridHandler() {
|
||||
return fluidGridHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public INetworkItemHandler getNetworkItemHandler() {
|
||||
return networkItemHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoved() {
|
||||
nodeGraph.disconnectAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageCache<ItemStack> getItemStorageCache() {
|
||||
return itemStorage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageCache<FluidStack> getFluidStorageCache() {
|
||||
return fluidStorage;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ItemStack insertItem(@Nonnull ItemStack stack, int size, Action action) {
|
||||
if (stack.isEmpty()) {
|
||||
return stack;
|
||||
}
|
||||
|
||||
if (itemStorage.getStorages().isEmpty()) {
|
||||
return ItemHandlerHelper.copyStackWithSize(stack, size);
|
||||
}
|
||||
|
||||
ItemStack remainder = stack;
|
||||
|
||||
int inserted = 0;
|
||||
int insertedExternally = 0;
|
||||
|
||||
for (IStorage<ItemStack> storage : this.itemStorage.getStorages()) {
|
||||
if (storage.getAccessType() == AccessType.EXTRACT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int storedPre = storage.getStored();
|
||||
|
||||
remainder = storage.insert(remainder, size, action);
|
||||
|
||||
if (action == Action.PERFORM) {
|
||||
inserted += storage.getCacheDelta(storedPre, size, remainder);
|
||||
}
|
||||
|
||||
if (remainder.isEmpty()) {
|
||||
// The external storage is responsible for sending changes, we don't need to anymore
|
||||
if (storage instanceof IExternalStorage && action == Action.PERFORM) {
|
||||
((IExternalStorage) storage).update(this);
|
||||
|
||||
insertedExternally += size;
|
||||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
// The external storage is responsible for sending changes, we don't need to anymore
|
||||
if (size != remainder.getCount() && storage instanceof IExternalStorage && action == Action.PERFORM) {
|
||||
((IExternalStorage) storage).update(this);
|
||||
|
||||
insertedExternally += size - remainder.getCount();
|
||||
}
|
||||
|
||||
size = remainder.getCount();
|
||||
}
|
||||
}
|
||||
|
||||
if (action == Action.PERFORM && inserted - insertedExternally > 0) {
|
||||
itemStorage.add(stack, inserted - insertedExternally, false, false);
|
||||
}
|
||||
|
||||
return remainder;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ItemStack extractItem(@Nonnull ItemStack stack, int size, int flags, Action action, Predicate<IStorage<ItemStack>> filter) {
|
||||
if (stack.isEmpty()) {
|
||||
return stack;
|
||||
}
|
||||
|
||||
int requested = size;
|
||||
int received = 0;
|
||||
|
||||
int extractedExternally = 0;
|
||||
|
||||
ItemStack newStack = ItemStack.EMPTY;
|
||||
|
||||
for (IStorage<ItemStack> storage : this.itemStorage.getStorages()) {
|
||||
ItemStack took = ItemStack.EMPTY;
|
||||
|
||||
if (filter.test(storage) && storage.getAccessType() != AccessType.INSERT) {
|
||||
took = storage.extract(stack, requested - received, flags, action);
|
||||
}
|
||||
|
||||
if (!took.isEmpty()) {
|
||||
// The external storage is responsible for sending changes, we don't need to anymore
|
||||
if (storage instanceof IExternalStorage && action == Action.PERFORM) {
|
||||
((IExternalStorage) storage).update(this);
|
||||
|
||||
extractedExternally += took.getCount();
|
||||
}
|
||||
|
||||
if (newStack.isEmpty()) {
|
||||
newStack = took;
|
||||
} else {
|
||||
newStack.grow(took.getCount());
|
||||
}
|
||||
|
||||
received += took.getCount();
|
||||
}
|
||||
|
||||
if (requested == received) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newStack.getCount() - extractedExternally > 0 && action == Action.PERFORM) {
|
||||
itemStorage.remove(newStack, newStack.getCount() - extractedExternally, false);
|
||||
}
|
||||
|
||||
return newStack;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public FluidStack insertFluid(@Nonnull FluidStack stack, int size, Action action) {
|
||||
if (stack.isEmpty()) {
|
||||
return stack;
|
||||
}
|
||||
|
||||
if (fluidStorage.getStorages().isEmpty()) {
|
||||
return StackUtils.copy(stack, size);
|
||||
}
|
||||
|
||||
FluidStack remainder = stack;
|
||||
|
||||
int inserted = 0;
|
||||
int insertedExternally = 0;
|
||||
|
||||
for (IStorage<FluidStack> storage : this.fluidStorage.getStorages()) {
|
||||
if (storage.getAccessType() == AccessType.EXTRACT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int storedPre = storage.getStored();
|
||||
|
||||
remainder = storage.insert(remainder, size, action);
|
||||
|
||||
if (action == Action.PERFORM) {
|
||||
inserted += storage.getCacheDelta(storedPre, size, remainder);
|
||||
}
|
||||
|
||||
if (remainder.isEmpty()) {
|
||||
// The external storage is responsible for sending changes, we don't need to anymore
|
||||
if (storage instanceof IExternalStorage && action == Action.PERFORM) {
|
||||
((IExternalStorage) storage).update(this);
|
||||
|
||||
insertedExternally += size;
|
||||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
// The external storage is responsible for sending changes, we don't need to anymore
|
||||
if (size != remainder.getAmount() && storage instanceof IExternalStorage && action == Action.PERFORM) {
|
||||
((IExternalStorage) storage).update(this);
|
||||
|
||||
insertedExternally += size - remainder.getAmount();
|
||||
}
|
||||
|
||||
size = remainder.getAmount();
|
||||
}
|
||||
}
|
||||
|
||||
if (action == Action.PERFORM && inserted - insertedExternally > 0) {
|
||||
fluidStorage.add(stack, inserted - insertedExternally, false, false);
|
||||
}
|
||||
|
||||
return remainder;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public FluidStack extractFluid(@Nonnull FluidStack stack, int size, int flags, Action action, Predicate<IStorage<FluidStack>> filter) {
|
||||
if (stack.isEmpty()) {
|
||||
return stack;
|
||||
}
|
||||
|
||||
int requested = size;
|
||||
int received = 0;
|
||||
|
||||
int extractedExternally = 0;
|
||||
|
||||
FluidStack newStack = FluidStack.EMPTY;
|
||||
|
||||
for (IStorage<FluidStack> storage : this.fluidStorage.getStorages()) {
|
||||
FluidStack took = FluidStack.EMPTY;
|
||||
|
||||
if (filter.test(storage) && storage.getAccessType() != AccessType.INSERT) {
|
||||
took = storage.extract(stack, requested - received, flags, action);
|
||||
}
|
||||
|
||||
if (!took.isEmpty()) {
|
||||
// The external storage is responsible for sending changes, we don't need to anymore
|
||||
if (storage instanceof IExternalStorage && action == Action.PERFORM) {
|
||||
((IExternalStorage) storage).update(this);
|
||||
|
||||
extractedExternally += took.getAmount();
|
||||
}
|
||||
|
||||
if (newStack.isEmpty()) {
|
||||
newStack = took;
|
||||
} else {
|
||||
newStack.grow(took.getAmount());
|
||||
}
|
||||
|
||||
received += took.getAmount();
|
||||
}
|
||||
|
||||
if (requested == received) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newStack.getAmount() - extractedExternally > 0 && action == Action.PERFORM) {
|
||||
fluidStorage.remove(newStack, newStack.getAmount() - extractedExternally, false);
|
||||
}
|
||||
|
||||
return newStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageTracker<ItemStack> getItemStorageTracker() {
|
||||
return itemStorageTracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageTracker<FluidStack> getFluidStorageTracker() {
|
||||
return fluidStorageTracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public INetwork readFromNbt(CompoundNBT tag) {
|
||||
if (tag.contains(NBT_ENERGY)) {
|
||||
this.energy.setStored(tag.getInt(NBT_ENERGY));
|
||||
}
|
||||
|
||||
redstoneMode = RedstoneMode.read(tag);
|
||||
|
||||
craftingManager.readFromNbt(tag);
|
||||
|
||||
if (tag.contains(NBT_ITEM_STORAGE_TRACKER)) {
|
||||
itemStorageTracker.readFromNbt(tag.getList(NBT_ITEM_STORAGE_TRACKER, Constants.NBT.TAG_COMPOUND));
|
||||
}
|
||||
|
||||
if (tag.contains(NBT_FLUID_STORAGE_TRACKER)) {
|
||||
fluidStorageTracker.readFromNbt(tag.getList(NBT_FLUID_STORAGE_TRACKER, Constants.NBT.TAG_COMPOUND));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT writeToNbt(CompoundNBT tag) {
|
||||
tag.putInt(NBT_ENERGY, this.energy.getEnergyStored());
|
||||
|
||||
redstoneMode.write(tag);
|
||||
|
||||
craftingManager.writeToNbt(tag);
|
||||
|
||||
tag.put(NBT_ITEM_STORAGE_TRACKER, itemStorageTracker.serializeNbt());
|
||||
tag.put(NBT_FLUID_STORAGE_TRACKER, fluidStorageTracker.serializeNbt());
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markDirty() {
|
||||
API.instance().getNetworkManager((ServerWorld) world).markForSaving();
|
||||
}
|
||||
|
||||
public static int getEnergyScaled(int stored, int capacity, int scale) {
|
||||
return (int) ((float) stored / (float) capacity * (float) scale);
|
||||
}
|
||||
|
||||
public ControllerBlock.EnergyType getEnergyType() {
|
||||
if (!redstoneMode.isEnabled(world, pos)) {
|
||||
return ControllerBlock.EnergyType.OFF;
|
||||
}
|
||||
|
||||
return getEnergyType(this.energy.getEnergyStored(), this.energy.getMaxEnergyStored());
|
||||
}
|
||||
|
||||
public static ControllerBlock.EnergyType getEnergyType(int stored, int capacity) {
|
||||
int energy = getEnergyScaled(stored, capacity, 100);
|
||||
|
||||
if (energy <= 0) {
|
||||
return ControllerBlock.EnergyType.OFF;
|
||||
} else if (energy <= 10) {
|
||||
return ControllerBlock.EnergyType.NEARLY_OFF;
|
||||
} else if (energy <= 20) {
|
||||
return ControllerBlock.EnergyType.NEARLY_ON;
|
||||
}
|
||||
|
||||
return ControllerBlock.EnergyType.ON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedstoneMode getRedstoneMode() {
|
||||
return redstoneMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRedstoneMode(RedstoneMode mode) {
|
||||
this.redstoneMode = mode;
|
||||
|
||||
markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnergyUsage() {
|
||||
int usage = RS.SERVER_CONFIG.getController().getBaseUsage();
|
||||
|
||||
for (INetworkNode node : nodeGraph.all()) {
|
||||
if (node.canUpdate()) {
|
||||
usage += node.getEnergyUsage();
|
||||
}
|
||||
}
|
||||
|
||||
return usage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEnergyStorage getEnergyStorage() {
|
||||
return energy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkType getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.network;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
public class NetworkListener {
|
||||
@SubscribeEvent
|
||||
public void onWorldTick(TickEvent.WorldTickEvent e) {
|
||||
if (!e.world.isRemote()) {
|
||||
if (e.phase == TickEvent.Phase.END) {
|
||||
e.world.getProfiler().startSection("network ticking");
|
||||
|
||||
for (INetwork network : API.instance().getNetworkManager((ServerWorld) e.world).all()) {
|
||||
network.update();
|
||||
}
|
||||
|
||||
e.world.getProfiler().endSection();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,126 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.network;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetworkManager;
|
||||
import com.raoulvdberge.refinedstorage.api.network.NetworkType;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.storage.WorldSavedData;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class NetworkManager extends WorldSavedData implements INetworkManager {
|
||||
public static final String NAME = "refinedstorage_networks";
|
||||
|
||||
private static final String NBT_NETWORKS = "Networks";
|
||||
private static final String NBT_TYPE = "Type";
|
||||
private static final String NBT_DATA = "Data";
|
||||
private static final String NBT_POS = "Pos";
|
||||
|
||||
private final World world;
|
||||
|
||||
private Logger logger = LogManager.getLogger(getClass());
|
||||
|
||||
private ConcurrentHashMap<BlockPos, INetwork> networks = new ConcurrentHashMap<>();
|
||||
|
||||
public NetworkManager(String name, World world) {
|
||||
super(name);
|
||||
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT tag) {
|
||||
if (tag.contains(NBT_NETWORKS)) {
|
||||
ListNBT networksTag = tag.getList(NBT_NETWORKS, Constants.NBT.TAG_COMPOUND);
|
||||
|
||||
this.networks.clear();
|
||||
|
||||
for (int i = 0; i < networksTag.size(); ++i) {
|
||||
CompoundNBT networkTag = networksTag.getCompound(i);
|
||||
|
||||
CompoundNBT data = networkTag.getCompound(NBT_DATA);
|
||||
BlockPos pos = BlockPos.fromLong(networkTag.getLong(NBT_POS));
|
||||
int type = networkTag.getInt(NBT_TYPE);
|
||||
|
||||
INetwork network = new Network(world, pos, NetworkType.values()[type]);
|
||||
|
||||
try {
|
||||
network = network.readFromNbt(data);
|
||||
} catch (Throwable t) {
|
||||
logger.error("Error while reading network", t);
|
||||
}
|
||||
|
||||
this.networks.put(pos, network);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT tag) {
|
||||
ListNBT list = new ListNBT();
|
||||
|
||||
for (INetwork network : all()) {
|
||||
try {
|
||||
CompoundNBT networkTag = new CompoundNBT();
|
||||
|
||||
networkTag.putLong(NBT_POS, network.getPosition().toLong());
|
||||
networkTag.put(NBT_DATA, network.writeToNbt(new CompoundNBT()));
|
||||
networkTag.putInt(NBT_TYPE, network.getType().ordinal());
|
||||
|
||||
list.add(networkTag);
|
||||
} catch (Throwable t) {
|
||||
logger.error("Error while saving network", t);
|
||||
}
|
||||
}
|
||||
|
||||
tag.put(NBT_NETWORKS, list);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public INetwork getNetwork(BlockPos pos) {
|
||||
return networks.get(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNetwork(BlockPos pos) {
|
||||
if (pos == null) {
|
||||
throw new IllegalArgumentException("Position cannot be null");
|
||||
}
|
||||
|
||||
networks.remove(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNetwork(BlockPos pos, INetwork network) {
|
||||
if (pos == null) {
|
||||
throw new IllegalArgumentException("Position cannot be null");
|
||||
}
|
||||
|
||||
if (network == null) {
|
||||
throw new IllegalArgumentException("Network cannot be null");
|
||||
}
|
||||
|
||||
networks.put(pos, network);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<INetwork> all() {
|
||||
return networks.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markForSaving() {
|
||||
markDirty();
|
||||
}
|
||||
}
|
@@ -105,7 +105,7 @@ public class NetworkNodeGraph implements INetworkNodeGraph {
|
||||
}
|
||||
|
||||
protected World getWorld() {
|
||||
return network.world();
|
||||
return network.getWorld();
|
||||
}
|
||||
|
||||
private void dropConflictingBlock(World world, BlockPos pos) {
|
||||
|
@@ -3,6 +3,7 @@ package com.raoulvdberge.refinedstorage.apiimpl.network;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy;
|
||||
import com.raoulvdberge.refinedstorage.api.network.security.Permission;
|
||||
import com.raoulvdberge.refinedstorage.api.util.Action;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.capability.NetworkNodeProxyCapability;
|
||||
@@ -10,6 +11,8 @@ import com.raoulvdberge.refinedstorage.util.WorldUtils;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
@@ -40,7 +43,7 @@ public class NetworkNodeListener {
|
||||
|
||||
if (placed != null) {
|
||||
placed.getCapability(NetworkNodeProxyCapability.NETWORK_NODE_PROXY_CAPABILITY).ifPresent(proxy -> {
|
||||
API.instance().discoverNode(e.getWorld(), e.getPos());
|
||||
discoverNode(e.getWorld(), e.getPos());
|
||||
|
||||
if (proxy.getNode() instanceof NetworkNode) {
|
||||
((NetworkNode) proxy.getNode()).setOwner(player.getGameProfile().getId());
|
||||
@@ -70,6 +73,25 @@ public class NetworkNodeListener {
|
||||
}
|
||||
}
|
||||
|
||||
private void discoverNode(IWorld world, BlockPos pos) {
|
||||
for (Direction facing : Direction.values()) {
|
||||
TileEntity tile = world.getTileEntity(pos.offset(facing));
|
||||
|
||||
if (tile != null) {
|
||||
INetworkNodeProxy proxy = tile.getCapability(NetworkNodeProxyCapability.NETWORK_NODE_PROXY_CAPABILITY, facing.getOpposite()).orElse(null);
|
||||
if (proxy != null) {
|
||||
INetworkNode node = proxy.getNode();
|
||||
|
||||
if (node.getNetwork() != null) {
|
||||
node.getNetwork().getNodeGraph().invalidate(Action.PERFORM, node.getNetwork().getWorld(), node.getNetwork().getPosition());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onBlockBreak(BlockEvent.BreakEvent e) {
|
||||
if (!e.getWorld().isRemote()) {
|
||||
|
@@ -87,7 +87,7 @@ public class NetworkNodeManager extends WorldSavedData implements INetworkNodeMa
|
||||
|
||||
list.add(nodeTag);
|
||||
} catch (Throwable t) {
|
||||
logger.error("Error while saving", t);
|
||||
logger.error("Error while saving network node", t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -148,7 +148,7 @@ public abstract class NetworkNode implements INetworkNode, INetworkNodeVisitor {
|
||||
onConnectedStateChange(network, canUpdate);
|
||||
|
||||
if (shouldRebuildGraphOnChange()) {
|
||||
network.getNodeGraph().invalidate(Action.PERFORM, network.world(), network.getPosition());
|
||||
network.getNodeGraph().invalidate(Action.PERFORM, network.getWorld(), network.getPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@ public class NetworkTransmitterNetworkNode extends NetworkNode {
|
||||
}
|
||||
|
||||
if (network != null) {
|
||||
network.getNodeGraph().invalidate(Action.PERFORM, network.world(), network.getPosition());
|
||||
network.getNodeGraph().invalidate(Action.PERFORM, network.getWorld(), network.getPosition());
|
||||
}
|
||||
});
|
||||
|
||||
|
@@ -0,0 +1,109 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.network.node;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetworkNodeVisitor;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class RootNetworkNode implements INetworkNode, INetworkNodeVisitor {
|
||||
private final INetwork network;
|
||||
private final World world;
|
||||
private final BlockPos pos;
|
||||
|
||||
public RootNetworkNode(INetwork network, World world, BlockPos pos) {
|
||||
this.network = network;
|
||||
this.world = world;
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnergyUsage() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack getItemStack() {
|
||||
BlockState state = world.getBlockState(pos);
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
Item item = Item.getItemFromBlock(state.getBlock());
|
||||
|
||||
return new ItemStack(item, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected(INetwork network) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(INetwork network) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public INetwork getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT tag) {
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markDirty() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Operator operator) {
|
||||
for (Direction facing : Direction.values()) {
|
||||
operator.apply(world, pos.offset(facing), facing.getOpposite());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return API.instance().isNetworkNodeEqual(this, o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return API.instance().getNetworkNodeHashCode(this);
|
||||
}
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
package com.raoulvdberge.refinedstorage.block;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.RS;
|
||||
import com.raoulvdberge.refinedstorage.api.network.NetworkType;
|
||||
import com.raoulvdberge.refinedstorage.container.ControllerContainer;
|
||||
import com.raoulvdberge.refinedstorage.tile.ControllerTile;
|
||||
import com.raoulvdberge.refinedstorage.util.BlockUtils;
|
||||
@@ -29,11 +30,6 @@ import net.minecraftforge.energy.CapabilityEnergy;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ControllerBlock extends Block {
|
||||
public enum Type {
|
||||
NORMAL,
|
||||
CREATIVE
|
||||
}
|
||||
|
||||
public enum EnergyType implements IStringSerializable {
|
||||
OFF("off"),
|
||||
NEARLY_OFF("nearly_off"),
|
||||
@@ -59,13 +55,13 @@ public class ControllerBlock extends Block {
|
||||
|
||||
public static final EnumProperty<EnergyType> ENERGY_TYPE = EnumProperty.create("energy_type", EnergyType.class);
|
||||
|
||||
private Type type;
|
||||
private NetworkType type;
|
||||
|
||||
public ControllerBlock(Type type) {
|
||||
public ControllerBlock(NetworkType type) {
|
||||
super(BlockUtils.DEFAULT_ROCK_PROPERTIES);
|
||||
|
||||
this.type = type;
|
||||
this.setRegistryName(RS.ID, type == Type.CREATIVE ? "creative_controller" : "controller");
|
||||
this.setRegistryName(RS.ID, type == NetworkType.CREATIVE ? "creative_controller" : "controller");
|
||||
this.setDefaultState(getStateContainer().getBaseState().with(ENERGY_TYPE, EnergyType.OFF));
|
||||
}
|
||||
|
||||
@@ -76,7 +72,7 @@ public class ControllerBlock extends Block {
|
||||
builder.add(ENERGY_TYPE);
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
public NetworkType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -118,7 +114,7 @@ public class ControllerBlock extends Block {
|
||||
player.openContainer(new INamedContainerProvider() {
|
||||
@Override
|
||||
public ITextComponent getDisplayName() {
|
||||
return new TranslationTextComponent("gui.refinedstorage." + (ControllerBlock.this.getType() == Type.CREATIVE ? "creative_" : "") + "controller");
|
||||
return new TranslationTextComponent("gui.refinedstorage." + (ControllerBlock.this.getType() == NetworkType.CREATIVE ? "creative_" : "") + "controller");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,8 +1,9 @@
|
||||
package com.raoulvdberge.refinedstorage.item.blockitem;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.RS;
|
||||
import com.raoulvdberge.refinedstorage.api.network.NetworkType;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.Network;
|
||||
import com.raoulvdberge.refinedstorage.block.ControllerBlock;
|
||||
import com.raoulvdberge.refinedstorage.tile.ControllerTile;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.energy.CapabilityEnergy;
|
||||
@@ -10,13 +11,13 @@ import net.minecraftforge.energy.IEnergyStorage;
|
||||
|
||||
public class ControllerBlockItem extends EnergyBlockItem {
|
||||
public ControllerBlockItem(ControllerBlock block) {
|
||||
super(block, new Item.Properties().group(RS.MAIN_GROUP).maxStackSize(1), block.getType() == ControllerBlock.Type.CREATIVE, () -> RS.SERVER_CONFIG.getController().getCapacity());
|
||||
super(block, new Item.Properties().group(RS.MAIN_GROUP).maxStackSize(1), block.getType() == NetworkType.CREATIVE, () -> RS.SERVER_CONFIG.getController().getCapacity());
|
||||
|
||||
this.setRegistryName(block.getRegistryName());
|
||||
this.addPropertyOverride(new ResourceLocation("energy_type"), (stack, world, entity) -> {
|
||||
IEnergyStorage storage = stack.getCapability(CapabilityEnergy.ENERGY).orElse(null);
|
||||
if (storage != null) {
|
||||
return ControllerTile.getEnergyType(storage.getEnergyStored(), storage.getMaxEnergyStored()).ordinal();
|
||||
return Network.getEnergyType(storage.getEnergyStored(), storage.getMaxEnergyStored()).ordinal();
|
||||
}
|
||||
|
||||
return ControllerBlock.EnergyType.OFF.ordinal();
|
||||
|
@@ -2,6 +2,7 @@ package com.raoulvdberge.refinedstorage.screen;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.raoulvdberge.refinedstorage.RS;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.Network;
|
||||
import com.raoulvdberge.refinedstorage.container.ControllerContainer;
|
||||
import com.raoulvdberge.refinedstorage.screen.widget.ScrollbarWidget;
|
||||
import com.raoulvdberge.refinedstorage.screen.widget.sidebutton.RedstoneModeSideButton;
|
||||
@@ -48,7 +49,7 @@ public class ControllerScreen extends BaseScreen<ControllerContainer> {
|
||||
|
||||
blit(x, y, 0, 0, xSize, ySize);
|
||||
|
||||
int energyBarHeightNew = ControllerTile.getEnergyScaled(ControllerTile.ENERGY_STORED.getValue(), ControllerTile.ENERGY_CAPACITY.getValue(), ENERGY_BAR_HEIGHT);
|
||||
int energyBarHeightNew = Network.getEnergyScaled(ControllerTile.ENERGY_STORED.getValue(), ControllerTile.ENERGY_CAPACITY.getValue(), ENERGY_BAR_HEIGHT);
|
||||
|
||||
blit(x + ENERGY_BAR_X, y + ENERGY_BAR_Y + ENERGY_BAR_HEIGHT - energyBarHeightNew, 178, ENERGY_BAR_HEIGHT - energyBarHeightNew, ENERGY_BAR_WIDTH, energyBarHeightNew);
|
||||
|
||||
|
@@ -1,86 +1,163 @@
|
||||
package com.raoulvdberge.refinedstorage.tile;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.raoulvdberge.refinedstorage.RS;
|
||||
import com.raoulvdberge.refinedstorage.RSTiles;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingManager;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetworkNodeGraph;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetworkNodeVisitor;
|
||||
import com.raoulvdberge.refinedstorage.api.network.grid.handler.IFluidGridHandler;
|
||||
import com.raoulvdberge.refinedstorage.api.network.grid.handler.IItemGridHandler;
|
||||
import com.raoulvdberge.refinedstorage.api.network.item.INetworkItemHandler;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetworkManager;
|
||||
import com.raoulvdberge.refinedstorage.api.network.NetworkType;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy;
|
||||
import com.raoulvdberge.refinedstorage.api.network.security.ISecurityManager;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.AccessType;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.IStorage;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.cache.IStorageCache;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.externalstorage.IExternalStorage;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.tracker.IStorageTracker;
|
||||
import com.raoulvdberge.refinedstorage.api.util.Action;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.CraftingManager;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.NetworkNodeGraph;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.FluidGridHandler;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.ItemGridHandler;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.item.NetworkItemHandler;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.security.SecurityManager;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.cache.FluidStorageCache;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.cache.ItemStorageCache;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.tracker.FluidStorageTracker;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.tracker.ItemStorageTracker;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.Network;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.network.node.RootNetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.block.ControllerBlock;
|
||||
import com.raoulvdberge.refinedstorage.energy.BaseEnergyStorage;
|
||||
import com.raoulvdberge.refinedstorage.tile.config.IRedstoneConfigurable;
|
||||
import com.raoulvdberge.refinedstorage.tile.config.RedstoneMode;
|
||||
import com.raoulvdberge.refinedstorage.tile.data.RSSerializers;
|
||||
import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.network.datasync.DataSerializers;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.energy.CapabilityEnergy;
|
||||
import net.minecraftforge.energy.IEnergyStorage;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static com.raoulvdberge.refinedstorage.capability.NetworkNodeProxyCapability.NETWORK_NODE_PROXY_CAPABILITY;
|
||||
|
||||
// TODO: Change INetwork to be offloaded from the tile.
|
||||
public class ControllerTile extends BaseTile implements ITickableTileEntity, INetwork, IRedstoneConfigurable, INetworkNode, INetworkNodeProxy<ControllerTile>, INetworkNodeVisitor {
|
||||
private static final Comparator<ClientNode> CLIENT_NODE_COMPARATOR = (left, right) -> {
|
||||
if (left.getEnergyUsage() == right.getEnergyUsage()) {
|
||||
return 0;
|
||||
public class ControllerTile extends BaseTile implements INetworkNodeProxy<RootNetworkNode>, IRedstoneConfigurable {
|
||||
public static final TileDataParameter<Integer, ControllerTile> REDSTONE_MODE = RedstoneMode.createParameter();
|
||||
public static final TileDataParameter<Integer, ControllerTile> ENERGY_USAGE = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.getNetwork().getEnergyUsage());
|
||||
public static final TileDataParameter<Integer, ControllerTile> ENERGY_STORED = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.getNetwork().getEnergyStorage().getEnergyStored());
|
||||
public static final TileDataParameter<Integer, ControllerTile> ENERGY_CAPACITY = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.getNetwork().getEnergyStorage().getMaxEnergyStored());
|
||||
public static final TileDataParameter<List<ClientNode>, ControllerTile> NODES = new TileDataParameter<>(RSSerializers.CLIENT_NODE_SERIALIZER, new ArrayList<>(), ControllerTile::collectClientNodes);
|
||||
|
||||
private static final String NBT_ENERGY_TYPE = "EnergyType";
|
||||
|
||||
private final LazyOptional<IEnergyStorage> energyProxyCap = LazyOptional.of(() -> getNetwork().getEnergyStorage());
|
||||
private final LazyOptional<INetworkNodeProxy<RootNetworkNode>> networkNodeProxyCap = LazyOptional.of(() -> this);
|
||||
|
||||
private final NetworkType type;
|
||||
private Network dummyNetwork;
|
||||
|
||||
public ControllerTile(NetworkType type) {
|
||||
super(type == NetworkType.CREATIVE ? RSTiles.CREATIVE_CONTROLLER : RSTiles.CONTROLLER);
|
||||
|
||||
dataManager.addWatchedParameter(REDSTONE_MODE);
|
||||
dataManager.addWatchedParameter(ENERGY_USAGE);
|
||||
dataManager.addWatchedParameter(ENERGY_STORED);
|
||||
dataManager.addParameter(ENERGY_CAPACITY);
|
||||
dataManager.addParameter(NODES);
|
||||
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT writeUpdate(CompoundNBT tag) {
|
||||
super.writeUpdate(tag);
|
||||
|
||||
tag.putInt(NBT_ENERGY_TYPE, ((Network) getNetwork()).getEnergyType().ordinal());
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readUpdate(CompoundNBT tag) {
|
||||
if (tag.contains(NBT_ENERGY_TYPE)) {
|
||||
world.setBlockState(pos, world.getBlockState(pos).with(ControllerBlock.ENERGY_TYPE, ControllerBlock.EnergyType.values()[tag.getInt(NBT_ENERGY_TYPE)]));
|
||||
}
|
||||
|
||||
return (left.getEnergyUsage() > right.getEnergyUsage()) ? -1 : 1;
|
||||
};
|
||||
super.readUpdate(tag);
|
||||
}
|
||||
|
||||
public static final TileDataParameter<Integer, ControllerTile> REDSTONE_MODE = RedstoneMode.createParameter();
|
||||
public static final TileDataParameter<Integer, ControllerTile> ENERGY_USAGE = new TileDataParameter<>(DataSerializers.VARINT, 0, ControllerTile::getEnergyUsage);
|
||||
public static final TileDataParameter<Integer, ControllerTile> ENERGY_STORED = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.energy.getEnergyStored());
|
||||
public static final TileDataParameter<Integer, ControllerTile> ENERGY_CAPACITY = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.energy.getMaxEnergyStored());
|
||||
public static final TileDataParameter<List<ClientNode>, ControllerTile> NODES = new TileDataParameter<>(RSSerializers.CLIENT_NODE_SERIALIZER, new ArrayList<>(), t -> {
|
||||
public INetwork getNetwork() {
|
||||
if (world.isRemote) {
|
||||
if (dummyNetwork == null) {
|
||||
dummyNetwork = new Network(world, pos, type);
|
||||
}
|
||||
|
||||
return dummyNetwork;
|
||||
}
|
||||
|
||||
INetwork network = API.instance().getNetworkManager((ServerWorld) world).getNetwork(pos);
|
||||
|
||||
if (network == null) {
|
||||
throw new IllegalStateException("No network present at " + pos);
|
||||
}
|
||||
|
||||
return network;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
super.validate();
|
||||
|
||||
if (!world.isRemote) {
|
||||
INetworkManager manager = API.instance().getNetworkManager((ServerWorld) world);
|
||||
|
||||
if (manager.getNetwork(pos) == null) {
|
||||
manager.setNetwork(pos, new Network(world, pos, type));
|
||||
manager.markForSaving();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
|
||||
if (!world.isRemote) {
|
||||
INetworkManager manager = API.instance().getNetworkManager((ServerWorld) world);
|
||||
|
||||
INetwork network = manager.getNetwork(pos);
|
||||
|
||||
manager.removeNetwork(pos);
|
||||
manager.markForSaving();
|
||||
|
||||
network.onRemoved();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public RootNetworkNode getNode() {
|
||||
return ((Network) getNetwork()).getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedstoneMode getRedstoneMode() {
|
||||
return ((Network) getNetwork()).getRedstoneMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRedstoneMode(RedstoneMode mode) {
|
||||
((Network) getNetwork()).setRedstoneMode(mode);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction direction) {
|
||||
if (cap == CapabilityEnergy.ENERGY) {
|
||||
return energyProxyCap.cast();
|
||||
}
|
||||
|
||||
if (cap == NETWORK_NODE_PROXY_CAPABILITY) {
|
||||
return networkNodeProxyCap.cast();
|
||||
}
|
||||
|
||||
return super.getCapability(cap, direction);
|
||||
}
|
||||
|
||||
private static List<ClientNode> collectClientNodes(ControllerTile tile) {
|
||||
List<ClientNode> nodes = new ArrayList<>();
|
||||
|
||||
for (INetworkNode node : t.nodeGraph.all()) {
|
||||
for (INetworkNode node : tile.getNetwork().getNodeGraph().all()) {
|
||||
if (node.canUpdate()) {
|
||||
ItemStack stack = node.getItemStack();
|
||||
|
||||
@@ -100,603 +177,8 @@ public class ControllerTile extends BaseTile implements ITickableTileEntity, INe
|
||||
}
|
||||
}
|
||||
|
||||
nodes.sort(CLIENT_NODE_COMPARATOR);
|
||||
nodes.sort((a, b) -> Integer.compare(b.getEnergyUsage(), a.getEnergyUsage()));
|
||||
|
||||
return nodes;
|
||||
});
|
||||
|
||||
private static final int THROTTLE_INACTIVE_TO_ACTIVE = 20;
|
||||
private static final int THROTTLE_ACTIVE_TO_INACTIVE = 4;
|
||||
|
||||
public static final String NBT_ENERGY = "Energy";
|
||||
private static final String NBT_ENERGY_TYPE = "EnergyType";
|
||||
|
||||
private static final String NBT_ITEM_STORAGE_TRACKER = "ItemStorageTracker";
|
||||
private static final String NBT_FLUID_STORAGE_TRACKER = "FluidStorageTracker";
|
||||
|
||||
private IItemGridHandler itemGridHandler = new ItemGridHandler(this);
|
||||
private IFluidGridHandler fluidGridHandler = new FluidGridHandler(this);
|
||||
|
||||
private INetworkItemHandler networkItemHandler = new NetworkItemHandler(this);
|
||||
|
||||
private INetworkNodeGraph nodeGraph = new NetworkNodeGraph(this);
|
||||
|
||||
private ICraftingManager craftingManager = new CraftingManager(this);
|
||||
|
||||
private ISecurityManager securityManager = new SecurityManager(this);
|
||||
|
||||
private IStorageCache<ItemStack> itemStorage = new ItemStorageCache(this);
|
||||
private ItemStorageTracker itemStorageTracker = new ItemStorageTracker(this::markDirty);
|
||||
|
||||
private IStorageCache<FluidStack> fluidStorage = new FluidStorageCache(this);
|
||||
private FluidStorageTracker fluidStorageTracker = new FluidStorageTracker(this::markDirty);
|
||||
|
||||
private final BaseEnergyStorage energy = new BaseEnergyStorage(RS.SERVER_CONFIG.getController().getCapacity(), RS.SERVER_CONFIG.getController().getMaxTransfer());
|
||||
|
||||
private final LazyOptional<IEnergyStorage> energyProxyCap = LazyOptional.of(() -> energy);
|
||||
private final LazyOptional<INetworkNodeProxy<ControllerTile>> networkNodeProxyCap = LazyOptional.of(() -> this);
|
||||
|
||||
private boolean throttlingDisabled = true; // Will be enabled after first update
|
||||
private boolean couldRun;
|
||||
private int ticksSinceUpdateChanged;
|
||||
|
||||
private ControllerBlock.Type type;
|
||||
private ControllerBlock.EnergyType lastEnergyType = ControllerBlock.EnergyType.OFF;
|
||||
|
||||
private RedstoneMode redstoneMode = RedstoneMode.IGNORE;
|
||||
|
||||
public ControllerTile(ControllerBlock.Type type) {
|
||||
super(type == ControllerBlock.Type.CREATIVE ? RSTiles.CREATIVE_CONTROLLER : RSTiles.CONTROLLER);
|
||||
|
||||
this.type = type;
|
||||
|
||||
dataManager.addWatchedParameter(REDSTONE_MODE);
|
||||
dataManager.addWatchedParameter(ENERGY_USAGE);
|
||||
dataManager.addWatchedParameter(ENERGY_STORED);
|
||||
dataManager.addParameter(ENERGY_CAPACITY);
|
||||
dataManager.addParameter(NODES);
|
||||
|
||||
nodeGraph.addListener(() -> dataManager.sendParameterToWatchers(ControllerTile.NODES));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPosition() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRun() {
|
||||
return this.energy.getEnergyStored() > 0 && redstoneMode.isEnabled(world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public INetworkNodeGraph getNodeGraph() {
|
||||
return nodeGraph;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISecurityManager getSecurityManager() {
|
||||
return securityManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICraftingManager getCraftingManager() {
|
||||
return craftingManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (!world.isRemote) {
|
||||
if (canRun()) {
|
||||
craftingManager.update();
|
||||
|
||||
if (!craftingManager.getTasks().isEmpty()) {
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
if (type == ControllerBlock.Type.NORMAL) {
|
||||
if (!RS.SERVER_CONFIG.getController().getUseEnergy()) {
|
||||
this.energy.setStored(this.energy.getMaxEnergyStored());
|
||||
} else if (this.energy.extractEnergy(getEnergyUsage(), true) >= 0) {
|
||||
this.energy.extractEnergy(getEnergyUsage(), false);
|
||||
} else {
|
||||
this.energy.setStored(0);
|
||||
}
|
||||
} else if (type == ControllerBlock.Type.CREATIVE) {
|
||||
this.energy.setStored(this.energy.getMaxEnergyStored());
|
||||
}
|
||||
|
||||
boolean canRun = canRun();
|
||||
|
||||
if (couldRun != canRun) {
|
||||
++ticksSinceUpdateChanged;
|
||||
|
||||
if ((canRun ? (ticksSinceUpdateChanged > THROTTLE_INACTIVE_TO_ACTIVE) : (ticksSinceUpdateChanged > THROTTLE_ACTIVE_TO_INACTIVE)) || throttlingDisabled) {
|
||||
ticksSinceUpdateChanged = 0;
|
||||
couldRun = canRun;
|
||||
throttlingDisabled = false;
|
||||
|
||||
nodeGraph.invalidate(Action.PERFORM, world, pos);
|
||||
securityManager.invalidate();
|
||||
}
|
||||
} else {
|
||||
ticksSinceUpdateChanged = 0;
|
||||
}
|
||||
|
||||
ControllerBlock.EnergyType energyType = getEnergyType();
|
||||
|
||||
if (lastEnergyType != energyType) {
|
||||
lastEnergyType = energyType;
|
||||
|
||||
world.setBlockState(pos, world.getBlockState(pos).with(ControllerBlock.ENERGY_TYPE, energyType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemGridHandler getItemGridHandler() {
|
||||
return itemGridHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidGridHandler getFluidGridHandler() {
|
||||
return fluidGridHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public INetworkItemHandler getNetworkItemHandler() {
|
||||
return networkItemHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
|
||||
if (world != null && !world.isRemote) {
|
||||
nodeGraph.disconnectAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageCache<ItemStack> getItemStorageCache() {
|
||||
return itemStorage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageCache<FluidStack> getFluidStorageCache() {
|
||||
return fluidStorage;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ItemStack insertItem(@Nonnull ItemStack stack, int size, Action action) {
|
||||
if (stack.isEmpty()) {
|
||||
return stack;
|
||||
}
|
||||
|
||||
if (itemStorage.getStorages().isEmpty()) {
|
||||
return ItemHandlerHelper.copyStackWithSize(stack, size);
|
||||
}
|
||||
|
||||
ItemStack remainder = stack;
|
||||
|
||||
int inserted = 0;
|
||||
int insertedExternally = 0;
|
||||
|
||||
for (IStorage<ItemStack> storage : this.itemStorage.getStorages()) {
|
||||
if (storage.getAccessType() == AccessType.EXTRACT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int storedPre = storage.getStored();
|
||||
|
||||
remainder = storage.insert(remainder, size, action);
|
||||
|
||||
if (action == Action.PERFORM) {
|
||||
inserted += storage.getCacheDelta(storedPre, size, remainder);
|
||||
}
|
||||
|
||||
if (remainder.isEmpty()) {
|
||||
// The external storage is responsible for sending changes, we don't need to anymore
|
||||
if (storage instanceof IExternalStorage && action == Action.PERFORM) {
|
||||
((IExternalStorage) storage).update(this);
|
||||
|
||||
insertedExternally += size;
|
||||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
// The external storage is responsible for sending changes, we don't need to anymore
|
||||
if (size != remainder.getCount() && storage instanceof IExternalStorage && action == Action.PERFORM) {
|
||||
((IExternalStorage) storage).update(this);
|
||||
|
||||
insertedExternally += size - remainder.getCount();
|
||||
}
|
||||
|
||||
size = remainder.getCount();
|
||||
}
|
||||
}
|
||||
|
||||
if (action == Action.PERFORM && inserted - insertedExternally > 0) {
|
||||
itemStorage.add(stack, inserted - insertedExternally, false, false);
|
||||
}
|
||||
|
||||
return remainder;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ItemStack extractItem(@Nonnull ItemStack stack, int size, int flags, Action action, Predicate<IStorage<ItemStack>> filter) {
|
||||
if (stack.isEmpty()) {
|
||||
return stack;
|
||||
}
|
||||
|
||||
int requested = size;
|
||||
int received = 0;
|
||||
|
||||
int extractedExternally = 0;
|
||||
|
||||
ItemStack newStack = ItemStack.EMPTY;
|
||||
|
||||
for (IStorage<ItemStack> storage : this.itemStorage.getStorages()) {
|
||||
ItemStack took = ItemStack.EMPTY;
|
||||
|
||||
if (filter.test(storage) && storage.getAccessType() != AccessType.INSERT) {
|
||||
took = storage.extract(stack, requested - received, flags, action);
|
||||
}
|
||||
|
||||
if (!took.isEmpty()) {
|
||||
// The external storage is responsible for sending changes, we don't need to anymore
|
||||
if (storage instanceof IExternalStorage && action == Action.PERFORM) {
|
||||
((IExternalStorage) storage).update(this);
|
||||
|
||||
extractedExternally += took.getCount();
|
||||
}
|
||||
|
||||
if (newStack.isEmpty()) {
|
||||
newStack = took;
|
||||
} else {
|
||||
newStack.grow(took.getCount());
|
||||
}
|
||||
|
||||
received += took.getCount();
|
||||
}
|
||||
|
||||
if (requested == received) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newStack.getCount() - extractedExternally > 0 && action == Action.PERFORM) {
|
||||
itemStorage.remove(newStack, newStack.getCount() - extractedExternally, false);
|
||||
}
|
||||
|
||||
return newStack;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public FluidStack insertFluid(@Nonnull FluidStack stack, int size, Action action) {
|
||||
if (stack.isEmpty()) {
|
||||
return stack;
|
||||
}
|
||||
|
||||
if (fluidStorage.getStorages().isEmpty()) {
|
||||
return StackUtils.copy(stack, size);
|
||||
}
|
||||
|
||||
FluidStack remainder = stack;
|
||||
|
||||
int inserted = 0;
|
||||
int insertedExternally = 0;
|
||||
|
||||
for (IStorage<FluidStack> storage : this.fluidStorage.getStorages()) {
|
||||
if (storage.getAccessType() == AccessType.EXTRACT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int storedPre = storage.getStored();
|
||||
|
||||
remainder = storage.insert(remainder, size, action);
|
||||
|
||||
if (action == Action.PERFORM) {
|
||||
inserted += storage.getCacheDelta(storedPre, size, remainder);
|
||||
}
|
||||
|
||||
if (remainder.isEmpty()) {
|
||||
// The external storage is responsible for sending changes, we don't need to anymore
|
||||
if (storage instanceof IExternalStorage && action == Action.PERFORM) {
|
||||
((IExternalStorage) storage).update(this);
|
||||
|
||||
insertedExternally += size;
|
||||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
// The external storage is responsible for sending changes, we don't need to anymore
|
||||
if (size != remainder.getAmount() && storage instanceof IExternalStorage && action == Action.PERFORM) {
|
||||
((IExternalStorage) storage).update(this);
|
||||
|
||||
insertedExternally += size - remainder.getAmount();
|
||||
}
|
||||
|
||||
size = remainder.getAmount();
|
||||
}
|
||||
}
|
||||
|
||||
if (action == Action.PERFORM && inserted - insertedExternally > 0) {
|
||||
fluidStorage.add(stack, inserted - insertedExternally, false, false);
|
||||
}
|
||||
|
||||
return remainder;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public FluidStack extractFluid(@Nonnull FluidStack stack, int size, int flags, Action action, Predicate<IStorage<FluidStack>> filter) {
|
||||
if (stack.isEmpty()) {
|
||||
return stack;
|
||||
}
|
||||
|
||||
int requested = size;
|
||||
int received = 0;
|
||||
|
||||
int extractedExternally = 0;
|
||||
|
||||
FluidStack newStack = FluidStack.EMPTY;
|
||||
|
||||
for (IStorage<FluidStack> storage : this.fluidStorage.getStorages()) {
|
||||
FluidStack took = FluidStack.EMPTY;
|
||||
|
||||
if (filter.test(storage) && storage.getAccessType() != AccessType.INSERT) {
|
||||
took = storage.extract(stack, requested - received, flags, action);
|
||||
}
|
||||
|
||||
if (!took.isEmpty()) {
|
||||
// The external storage is responsible for sending changes, we don't need to anymore
|
||||
if (storage instanceof IExternalStorage && action == Action.PERFORM) {
|
||||
((IExternalStorage) storage).update(this);
|
||||
|
||||
extractedExternally += took.getAmount();
|
||||
}
|
||||
|
||||
if (newStack.isEmpty()) {
|
||||
newStack = took;
|
||||
} else {
|
||||
newStack.grow(took.getAmount());
|
||||
}
|
||||
|
||||
received += took.getAmount();
|
||||
}
|
||||
|
||||
if (requested == received) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newStack.getAmount() - extractedExternally > 0 && action == Action.PERFORM) {
|
||||
fluidStorage.remove(newStack, newStack.getAmount() - extractedExternally, false);
|
||||
}
|
||||
|
||||
return newStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageTracker<ItemStack> getItemStorageTracker() {
|
||||
return itemStorageTracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageTracker<FluidStack> getFluidStorageTracker() {
|
||||
return fluidStorageTracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public World world() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT tag) {
|
||||
super.read(tag);
|
||||
|
||||
if (tag.contains(NBT_ENERGY)) {
|
||||
this.energy.setStored(tag.getInt(NBT_ENERGY));
|
||||
}
|
||||
|
||||
redstoneMode = RedstoneMode.read(tag);
|
||||
|
||||
craftingManager.readFromNbt(tag);
|
||||
|
||||
if (tag.contains(NBT_ITEM_STORAGE_TRACKER)) {
|
||||
itemStorageTracker.readFromNbt(tag.getList(NBT_ITEM_STORAGE_TRACKER, Constants.NBT.TAG_COMPOUND));
|
||||
}
|
||||
|
||||
if (tag.contains(NBT_FLUID_STORAGE_TRACKER)) {
|
||||
fluidStorageTracker.readFromNbt(tag.getList(NBT_FLUID_STORAGE_TRACKER, Constants.NBT.TAG_COMPOUND));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT tag) {
|
||||
super.write(tag);
|
||||
|
||||
tag.putInt(NBT_ENERGY, this.energy.getEnergyStored());
|
||||
|
||||
redstoneMode.write(tag);
|
||||
|
||||
craftingManager.writeToNbt(tag);
|
||||
|
||||
tag.put(NBT_ITEM_STORAGE_TRACKER, itemStorageTracker.serializeNbt());
|
||||
tag.put(NBT_FLUID_STORAGE_TRACKER, fluidStorageTracker.serializeNbt());
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT writeUpdate(CompoundNBT tag) {
|
||||
super.writeUpdate(tag);
|
||||
|
||||
tag.putInt(NBT_ENERGY_TYPE, getEnergyType().ordinal());
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readUpdate(CompoundNBT tag) {
|
||||
if (tag.contains(NBT_ENERGY_TYPE)) {
|
||||
world.setBlockState(pos, world.getBlockState(pos).with(ControllerBlock.ENERGY_TYPE, ControllerBlock.EnergyType.values()[tag.getInt(NBT_ENERGY_TYPE)]));
|
||||
}
|
||||
|
||||
super.readUpdate(tag);
|
||||
}
|
||||
|
||||
public static int getEnergyScaled(int stored, int capacity, int scale) {
|
||||
return (int) ((float) stored / (float) capacity * (float) scale);
|
||||
}
|
||||
|
||||
private ControllerBlock.EnergyType getEnergyType() {
|
||||
if (!redstoneMode.isEnabled(world, pos)) {
|
||||
return ControllerBlock.EnergyType.OFF;
|
||||
}
|
||||
|
||||
return getEnergyType(this.energy.getEnergyStored(), this.energy.getMaxEnergyStored());
|
||||
}
|
||||
|
||||
public static ControllerBlock.EnergyType getEnergyType(int stored, int capacity) {
|
||||
int energy = getEnergyScaled(stored, capacity, 100);
|
||||
|
||||
if (energy <= 0) {
|
||||
return ControllerBlock.EnergyType.OFF;
|
||||
} else if (energy <= 10) {
|
||||
return ControllerBlock.EnergyType.NEARLY_OFF;
|
||||
} else if (energy <= 20) {
|
||||
return ControllerBlock.EnergyType.NEARLY_ON;
|
||||
}
|
||||
|
||||
return ControllerBlock.EnergyType.ON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedstoneMode getRedstoneMode() {
|
||||
return redstoneMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRedstoneMode(RedstoneMode mode) {
|
||||
this.redstoneMode = mode;
|
||||
|
||||
markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnergyUsage() {
|
||||
int usage = RS.SERVER_CONFIG.getController().getBaseUsage();
|
||||
|
||||
for (INetworkNode node : nodeGraph.all()) {
|
||||
if (node.canUpdate()) {
|
||||
usage += node.getEnergyUsage();
|
||||
}
|
||||
}
|
||||
|
||||
return usage;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack getItemStack() {
|
||||
BlockState state = world.getBlockState(pos);
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
Item item = Item.getItemFromBlock(state.getBlock());
|
||||
|
||||
return new ItemStack(item, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected(INetwork network) {
|
||||
Preconditions.checkArgument(this == network, "Should not be connected to another controller");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(INetwork network) {
|
||||
Preconditions.checkArgument(this == network, "Should not be connected to another controller");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public INetwork getNetwork() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
// This is update from INetworkNode
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction direction) {
|
||||
if (cap == CapabilityEnergy.ENERGY) {
|
||||
return energyProxyCap.cast();
|
||||
}
|
||||
|
||||
if (cap == NETWORK_NODE_PROXY_CAPABILITY) {
|
||||
return networkNodeProxyCap.cast();
|
||||
}
|
||||
|
||||
return super.getCapability(cap, direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ControllerTile getNode() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Operator operator) {
|
||||
for (Direction facing : Direction.values()) {
|
||||
operator.apply(world, pos.offset(facing), facing.getOpposite());
|
||||
}
|
||||
}
|
||||
|
||||
// Cannot use API#getNetworkNodeHashCode or API#isNetworkNodeEqual: it will crash with a AbstractMethodError (getPos).
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof ControllerTile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ControllerTile otherController = (ControllerTile) o;
|
||||
|
||||
if (world.getDimension().getType() != otherController.world.getDimension().getType()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return pos.equals(otherController.pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = pos.hashCode();
|
||||
result = 31 * result + world.getDimension().getType().getId();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@@ -100,7 +100,7 @@ public abstract class NetworkNodeTile<N extends NetworkNode> extends BaseTile im
|
||||
manager.markForSaving();
|
||||
|
||||
if (node != null && node.getNetwork() != null) {
|
||||
node.getNetwork().getNodeGraph().invalidate(Action.PERFORM, node.getNetwork().world(), node.getNetwork().getPosition());
|
||||
node.getNetwork().getNodeGraph().invalidate(Action.PERFORM, node.getNetwork().getWorld(), node.getNetwork().getPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user