From b895ff60e9ea3d78c3c250432b4a5433fcab38a8 Mon Sep 17 00:00:00 2001 From: Martmists Date: Sat, 7 Mar 2020 17:26:49 +0100 Subject: [PATCH] Better networking, more models & textures --- src/main/java/com/martmists/ynet/YNetMod.java | 22 ++- .../blockentities/ConnectorBlockEntity.java | 24 +++ .../blockentities/ControllerBlockEntity.java | 79 +++------ .../com/martmists/ynet/blocks/CableBlock.java | 42 +++++ .../martmists/ynet/blocks/ConnectorBlock.java | 150 ++++++++++-------- .../ynet/blocks/ControllerBlock.java | 30 ++++ .../ynet/event/ProviderTickCallback.java | 8 +- .../accessors/InventoryStacksAccessor.java | 7 +- .../providers/energy/PowerAcceptorMixin.java | 3 +- .../item/LootableContainerBlockMixin.java | 8 +- .../com/martmists/ynet/network/Channel.java | 10 ++ .../ynet/network/ConnectorConfiguration.java | 17 ++ .../com/martmists/ynet/network/Network.java | 119 ++++++++++++++ .../assets/ynet/blockstates/connector.json | 119 ++++++++++++++ .../assets/ynet/models/block/connector.json | 37 +++++ .../assets/ynet/textures/block/connector.png | Bin 0 -> 128 bytes .../assets/ynet/textures/block/pipe.png | Bin 105 -> 99 bytes 17 files changed, 536 insertions(+), 139 deletions(-) create mode 100644 src/main/java/com/martmists/ynet/blockentities/ConnectorBlockEntity.java create mode 100644 src/main/java/com/martmists/ynet/network/Channel.java create mode 100644 src/main/java/com/martmists/ynet/network/ConnectorConfiguration.java create mode 100644 src/main/java/com/martmists/ynet/network/Network.java create mode 100644 src/main/resources/assets/ynet/blockstates/connector.json create mode 100644 src/main/resources/assets/ynet/models/block/connector.json create mode 100644 src/main/resources/assets/ynet/textures/block/connector.png diff --git a/src/main/java/com/martmists/ynet/YNetMod.java b/src/main/java/com/martmists/ynet/YNetMod.java index 4f56178..3438cf5 100644 --- a/src/main/java/com/martmists/ynet/YNetMod.java +++ b/src/main/java/com/martmists/ynet/YNetMod.java @@ -3,11 +3,13 @@ package com.martmists.ynet; import com.martmists.ynet.api.BaseProvider; import com.martmists.ynet.api.EnergyProvider; import com.martmists.ynet.api.ItemProvider; +import com.martmists.ynet.blockentities.ConnectorBlockEntity; import com.martmists.ynet.blockentities.ControllerBlockEntity; import com.martmists.ynet.blocks.CableBlock; import com.martmists.ynet.blocks.ConnectorBlock; import com.martmists.ynet.blocks.ControllerBlock; import com.martmists.ynet.event.ProviderTickCallback; +import com.martmists.ynet.network.ConnectorConfiguration; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder; import net.minecraft.block.Block; @@ -19,11 +21,14 @@ import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.util.ActionResult; import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.SimpleRegistry; import java.util.HashMap; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; public class YNetMod implements ModInitializer { public static ItemGroup YNET_GROUP = FabricItemGroupBuilder.build( @@ -36,6 +41,11 @@ public class YNetMod implements ModInitializer { ); public static CableBlock CABLE = register("cable", new CableBlock(Block.Settings.of(Material.METAL))); public static ConnectorBlock CONNECTOR = register("connector", new ConnectorBlock(Block.Settings.of(Material.METAL))); + public static BlockEntityType CONNECTOR_BE = Registry.register( + Registry.BLOCK_ENTITY_TYPE, + new Identifier("ynet", "connector"), + BlockEntityType.Builder.create(ConnectorBlockEntity::new, CONNECTOR).build(null) + ); public static ControllerBlock CONTROLLER = register("controller", new ControllerBlock(Block.Settings.of(Material.METAL))); public static BlockEntityType CONTROLLER_BE = Registry.register( Registry.BLOCK_ENTITY_TYPE, @@ -49,17 +59,19 @@ public class YNetMod implements ModInitializer { @Override public void onInitialize() { System.out.println("YNet loaded!"); - register("ynet:item", ItemProvider.class, (ItemProvider[] listeners, ControllerBlockEntity be) -> { + register("ynet:item", ItemProvider.class, (listeners, be) -> { // TODO: // - Get matching channels from ControllerBlockEntity - // - Find a way to route all items (+ filters? - return ActionResult.SUCCESS; + // - Find a way to route all items (+ filters?) + }); - register("ynet:energy", EnergyProvider.class, (EnergyProvider[] listeners, ControllerBlockEntity be) -> { + register("ynet:energy", EnergyProvider.class, (listeners, be) -> { // TODO: // - Get matching channels from ControllerBlockEntity // - Find a way to route all energy - return ActionResult.SUCCESS; + Set takeEnergy = listeners.stream().filter(config -> config.state == ConnectorConfiguration.State.INPUT).collect(Collectors.toSet()); + Set giveEnergy = listeners.stream().filter(config -> config.state == ConnectorConfiguration.State.OUTPUT).collect(Collectors.toSet()); + }); // TODO: // - Add support for configuring redstone signals on connectors diff --git a/src/main/java/com/martmists/ynet/blockentities/ConnectorBlockEntity.java b/src/main/java/com/martmists/ynet/blockentities/ConnectorBlockEntity.java new file mode 100644 index 0000000..8864b43 --- /dev/null +++ b/src/main/java/com/martmists/ynet/blockentities/ConnectorBlockEntity.java @@ -0,0 +1,24 @@ +package com.martmists.ynet.blockentities; + +import com.martmists.ynet.YNetMod; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.util.math.Direction; + +import java.util.HashMap; +import java.util.Map; + +public class ConnectorBlockEntity extends BlockEntity { + private Map redstoneState = new HashMap<>(); + + public ConnectorBlockEntity() { + super(YNetMod.CONNECTOR_BE); + } + + public void setRedstonePower(Direction d, int p) { + redstoneState.put(d, p); + } + + public int getRedstonePower(Direction d) { + return redstoneState.getOrDefault(d, 0); + } +} diff --git a/src/main/java/com/martmists/ynet/blockentities/ControllerBlockEntity.java b/src/main/java/com/martmists/ynet/blockentities/ControllerBlockEntity.java index 70af954..31f4ba5 100644 --- a/src/main/java/com/martmists/ynet/blockentities/ControllerBlockEntity.java +++ b/src/main/java/com/martmists/ynet/blockentities/ControllerBlockEntity.java @@ -5,6 +5,8 @@ import com.martmists.ynet.api.BaseProvider; import com.martmists.ynet.blocks.CableBlock; import com.martmists.ynet.blocks.ConnectorBlock; import com.martmists.ynet.event.ProviderTickCallback; +import com.martmists.ynet.network.Channel; +import com.martmists.ynet.network.Network; import net.minecraft.block.Block; import net.minecraft.block.entity.BlockEntity; import net.minecraft.util.Tickable; @@ -16,80 +18,47 @@ import java.util.*; import java.util.stream.Collectors; public class ControllerBlockEntity extends BlockEntity implements Tickable { + public Network network; + public Channel[] channels = new Channel[9]; + public ControllerBlockEntity() { super(YNetMod.CONTROLLER_BE); + this.network = new Network(); + this.network.setController(pos); } // TODO: // - Add configurable channels // - Add a way to get input/output blocks from said channel - private Block[] getConnectedBlocks() { - ArrayDeque toSearch = new ArrayDeque(); - toSearch.push(pos); - List searched = new ArrayList<>(); - searched.add(pos); + public void updateNetwork() { + network.reloadAllNodes(world); + } + + private List getConnectedProviders(Set connectors) { List providers = new ArrayList<>(); - while (!toSearch.isEmpty()){ - BlockPos p = toSearch.removeFirst(); - for (BlockPos p2 : Arrays.asList(p.up(), p.down(), p.north(), p.south(), p.east(), p.west())) { - if (searched.contains(p2)) { - continue; - } - searched.add(p2); - Block b = world.getBlockState(p2).getBlock(); - if (b == YNetMod.CABLE || b == YNetMod.CONNECTOR) { - toSearch.add(p2); - } else if (b instanceof BaseProvider) { - providers.add(p2); + for (BlockPos c : connectors){ + for (BlockPos offset : new BlockPos[]{ c.up(), c.down(), c.north(), c.east(), c.south(), c.west() }){ + if (world.getBlockState(offset).getBlock() instanceof BaseProvider) { + providers.add(offset); } } } - return (Block[]) providers.stream().map(p -> world.getBlockState(p).getBlock()).toArray(); + return providers; } @Override public void tick() { // TODO: // Collect all connected blocks - Block[] blocks = getConnectedBlocks(); - - Map, List> blockMap = new HashMap<>(); - for (Block b : blocks) { - Class bClass = b.getClass(); - if (!tMap.containsKey(bClass)){ - Set> set = new HashSet<>(); - findProviderTypes(bClass, set); - tMap.put(bClass, set); - } - for (Class clazz : tMap.get(bClass)){ - blockMap.putIfAbsent(clazz, new ArrayList<>()); - blockMap.get(clazz).add((BaseProvider)b); - } + if (network.cables == null) { + network.setController(pos); + updateNetwork(); } - - for (Class clazz : blockMap.keySet()) { - dispatch(clazz, blockMap.get(clazz)); - } - } - - private

void dispatch(Class clazz, List

blockMap) { - ProviderTickCallback

provider = (ProviderTickCallback

) YNetMod.PROVIDERS.get(clazz); - provider.interact(blockMap.toArray(provider.createArray((Class

) clazz)), this); - - } - - // Ugly hack by Pyrofab - private static Map, Set>> tMap = new HashMap<>(); - private static void findProviderTypes(Class cls, Set> ret) { - tMap.putIfAbsent(cls, ret); - if (cls != Object.class) { - if (BaseProvider.class.isAssignableFrom(cls)) { - ret.add((Class) cls); - } - findProviderTypes(cls.getSuperclass(), ret); - for (Class itf : cls.getInterfaces()) { - findProviderTypes(itf, ret); + Set blocks = network.getProviders(world); + for (Channel ch : channels) { + if (ch != null) { + YNetMod.PROVIDERS.get(ch.providerType).interact(ch.connectorSettings, this); } } } diff --git a/src/main/java/com/martmists/ynet/blocks/CableBlock.java b/src/main/java/com/martmists/ynet/blocks/CableBlock.java index 5a665c4..9ebeae6 100644 --- a/src/main/java/com/martmists/ynet/blocks/CableBlock.java +++ b/src/main/java/com/martmists/ynet/blocks/CableBlock.java @@ -2,17 +2,26 @@ package com.martmists.ynet.blocks; import com.martmists.ynet.YNetMod; import com.martmists.ynet.api.BaseProvider; +import com.martmists.ynet.blockentities.ControllerBlockEntity; +import com.martmists.ynet.network.Network; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.ConnectingBlock; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemStack; import net.minecraft.state.StateManager; import net.minecraft.state.property.Property; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.BlockView; import net.minecraft.world.IWorld; +import net.minecraft.world.World; + +import java.util.HashSet; +import java.util.Set; public class CableBlock extends ConnectingBlock { public CableBlock(Settings settings) { @@ -48,6 +57,39 @@ public class CableBlock extends ConnectingBlock { } } + @Override + public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) { + super.onBreak(world, pos, state, player); + Set controllers = new HashSet<>(); + + // No longer connected, check all neighbors + Network.getConnectedControllers(world, pos, controllers); + + System.out.println("Controllers: " + controllers); // Empty? + for (BlockPos p : controllers){ + ControllerBlockEntity be = (ControllerBlockEntity)world.getBlockEntity(p); + be.updateNetwork(); + } + } + + @Override + public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) { + Set controllers = new HashSet<>(); + + // TODO: Find a better way to do this instead of a BFS through the world + Network.getConnectedControllers(world, pos, controllers); + + System.out.println("Controllers: " + controllers); + for (BlockPos p : controllers){ + ControllerBlockEntity be = (ControllerBlockEntity)world.getBlockEntity(p); + // be.network.cables.add(p); + Set known = new HashSet<>(); + known.addAll(be.network.cables); + known.addAll(be.network.connectors); + Network.getConnectedBlocks(world, pos, known, be.network.cables, be.network.connectors); + } + } + public BlockState withConnectionProperties(BlockView world, BlockPos pos) { Block block = world.getBlockState(pos.down()).getBlock(); Block block2 = world.getBlockState(pos.up()).getBlock(); diff --git a/src/main/java/com/martmists/ynet/blocks/ConnectorBlock.java b/src/main/java/com/martmists/ynet/blocks/ConnectorBlock.java index d73f3b4..14e3bc9 100644 --- a/src/main/java/com/martmists/ynet/blocks/ConnectorBlock.java +++ b/src/main/java/com/martmists/ynet/blocks/ConnectorBlock.java @@ -2,12 +2,15 @@ package com.martmists.ynet.blocks; import com.martmists.ynet.YNetMod; import com.martmists.ynet.api.BaseProvider; -import com.sun.org.apache.xpath.internal.operations.Bool; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.ConnectingBlock; -import net.minecraft.block.RedstoneWireBlock; +import com.martmists.ynet.blockentities.ConnectorBlockEntity; +import com.martmists.ynet.blockentities.ControllerBlockEntity; +import com.martmists.ynet.network.Network; +import net.minecraft.block.*; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemStack; import net.minecraft.state.StateManager; import net.minecraft.state.property.BooleanProperty; import net.minecraft.state.property.IntProperty; @@ -16,19 +19,27 @@ import net.minecraft.util.math.Direction; import net.minecraft.world.BlockView; import net.minecraft.world.IWorld; import net.minecraft.world.ModifiableWorld; +import net.minecraft.world.World; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; -public class ConnectorBlock extends ConnectingBlock { - public static final IntProperty NORTH_REDSTONE = IntProperty.of("NORTH_REDSTONE", 0, 15); - public static final IntProperty EAST_REDSTONE = IntProperty.of("EAST_REDSTONE", 0, 15); - public static final IntProperty SOUTH_REDSTONE = IntProperty.of("SOUTH_REDSTONE", 0, 15); - public static final IntProperty WEST_REDSTONE = IntProperty.of("WEST_REDSTONE", 0, 15); - public static final IntProperty UP_REDSTONE = IntProperty.of("UP_REDSTONE", 0, 15); - public static final IntProperty DOWN_REDSTONE = IntProperty.of("DOWN_REDSTONE", 0, 15); +public class ConnectorBlock extends ConnectingBlock implements BlockEntityProvider { + private static BooleanProperty NORTH_CABLE = BooleanProperty.of("north_cable"); + private static BooleanProperty EAST_CABLE = BooleanProperty.of("east_cable"); + private static BooleanProperty SOUTH_CABLE = BooleanProperty.of("south_cable"); + private static BooleanProperty WEST_CABLE = BooleanProperty.of("west_cable"); + private static BooleanProperty UP_CABLE = BooleanProperty.of("up_cable"); + private static BooleanProperty DOWN_CABLE = BooleanProperty.of("down_cable"); + private static Map CABLE_FACING_PROPERTIES = new HashMap<>(); + + static { + CABLE_FACING_PROPERTIES.put(Direction.NORTH, NORTH_CABLE); + CABLE_FACING_PROPERTIES.put(Direction.EAST, EAST_CABLE); + CABLE_FACING_PROPERTIES.put(Direction.SOUTH, SOUTH_CABLE); + CABLE_FACING_PROPERTIES.put(Direction.WEST, WEST_CABLE); + CABLE_FACING_PROPERTIES.put(Direction.UP, UP_CABLE); + CABLE_FACING_PROPERTIES.put(Direction.DOWN, DOWN_CABLE); + } public ConnectorBlock(Settings settings) { super(0.1875F, settings); @@ -39,18 +50,18 @@ public class ConnectorBlock extends ConnectingBlock { .with(WEST, false) .with(UP, false) .with(DOWN, false) - .with(NORTH_REDSTONE, 0) - .with(EAST_REDSTONE, 0) - .with(SOUTH_REDSTONE, 0) - .with(WEST_REDSTONE, 0) - .with(UP_REDSTONE, 0) - .with(DOWN_REDSTONE, 0) + .with(NORTH_CABLE, false) + .with(EAST_CABLE, false) + .with(SOUTH_CABLE, false) + .with(WEST_CABLE, false) + .with(UP_CABLE, false) + .with(DOWN_CABLE, false) ); } @Override protected void appendProperties(StateManager.Builder builder) { - builder.add(NORTH, EAST, SOUTH, WEST, UP, DOWN); + builder.add(NORTH, EAST, SOUTH, WEST, UP, DOWN, NORTH_CABLE, EAST_CABLE, SOUTH_CABLE, WEST_CABLE, UP_CABLE, DOWN_CABLE); } @Override @@ -65,19 +76,9 @@ public class ConnectorBlock extends ConnectingBlock { return super.getStateForNeighborUpdate(state, facing, neighborState, world, pos, neighborPos); } else { Block block = neighborState.getBlock(); - return state.with(FACING_PROPERTIES.get(facing), block == this || block == YNetMod.CABLE || block == YNetMod.CONTROLLER || block instanceof BaseProvider); - } - } - - public T[] getProviders(BlockView world, BlockPos pos) { - List providers = new ArrayList<>(); - for (BlockPos position : new BlockPos[]{ pos.up(), pos.down(), pos.north(), pos.east(), pos.south(), pos.west() }){ - Block b = world.getBlockState(position).getBlock(); - if (b instanceof BaseProvider){ - providers.add((T)b); - } + return state.with(FACING_PROPERTIES.get(facing), block == this || block == YNetMod.CONTROLLER || block instanceof BaseProvider) + .with(CABLE_FACING_PROPERTIES.get(facing), block == YNetMod.CABLE); } - return (T[])providers.toArray(); } public BlockState withConnectionProperties(BlockView world, BlockPos pos) { @@ -88,12 +89,18 @@ public class ConnectorBlock extends ConnectingBlock { Block block5 = world.getBlockState(pos.south()).getBlock(); Block block6 = world.getBlockState(pos.west()).getBlock(); return this.getDefaultState() - .with(DOWN, block == this || block == YNetMod.CABLE || block == YNetMod.CONTROLLER || block instanceof BaseProvider) - .with(UP, block2 == this || block2 == YNetMod.CABLE || block2 == YNetMod.CONTROLLER || block2 instanceof BaseProvider) - .with(NORTH, block3 == this || block3 == YNetMod.CABLE || block3 == YNetMod.CONTROLLER || block3 instanceof BaseProvider) - .with(EAST, block4 == this || block4 == YNetMod.CABLE || block4 == YNetMod.CONTROLLER || block4 instanceof BaseProvider) - .with(SOUTH, block5 == this || block5 == YNetMod.CABLE || block5 == YNetMod.CONTROLLER || block5 instanceof BaseProvider) - .with(WEST, block6 == this || block6 == YNetMod.CABLE || block6 == YNetMod.CONTROLLER || block6 instanceof BaseProvider); + .with(DOWN, block == this || block == YNetMod.CONTROLLER || block instanceof BaseProvider) + .with(UP, block2 == this || block2 == YNetMod.CONTROLLER || block2 instanceof BaseProvider) + .with(NORTH, block3 == this || block3 == YNetMod.CONTROLLER || block3 instanceof BaseProvider) + .with(EAST, block4 == this || block4 == YNetMod.CONTROLLER || block4 instanceof BaseProvider) + .with(SOUTH, block5 == this || block5 == YNetMod.CONTROLLER || block5 instanceof BaseProvider) + .with(WEST, block6 == this || block6 == YNetMod.CONTROLLER || block6 instanceof BaseProvider) + .with(DOWN_CABLE, block == YNetMod.CABLE) + .with(UP_CABLE, block2 == YNetMod.CABLE) + .with(NORTH_CABLE, block3 == YNetMod.CABLE) + .with(EAST_CABLE, block4 == YNetMod.CABLE) + .with(SOUTH_CABLE, block5 == YNetMod.CABLE) + .with(WEST_CABLE, block6 == YNetMod.CABLE); } @Override @@ -103,43 +110,52 @@ public class ConnectorBlock extends ConnectingBlock { @Override public int getWeakRedstonePower(BlockState state, BlockView world, BlockPos pos, Direction facing) { - return state.get(getProp(facing)); + return ((ConnectorBlockEntity)world.getBlockEntity(pos)).getRedstonePower(facing); } public void setRedstoneOutput(Direction facing, BlockView world, BlockPos pos, int strength) { + ((ConnectorBlockEntity)world.getBlockEntity(pos)).setRedstonePower(facing, strength); + } + + @Override + public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) { + super.onBreak(world, pos, state, player); + Set controllers = new HashSet<>(); - ((ModifiableWorld)world).setBlockState(pos, world.getBlockState(pos).with(getProp(facing), strength), 3); + Network.getConnectedControllers(world, pos, controllers); + + System.out.println("Controllers: " + controllers); // Empty? + for (BlockPos p : controllers){ + ControllerBlockEntity be = (ControllerBlockEntity)world.getBlockEntity(p); + be.updateNetwork(); + } } - private IntProperty getProp(Direction facing) { - IntProperty p; - switch (facing){ - case DOWN: - p = DOWN_REDSTONE; - break; - case UP: - p = UP_REDSTONE; - break; - case NORTH: - p = NORTH_REDSTONE; - break; - case SOUTH: - p = SOUTH_REDSTONE; - break; - case WEST: - p = WEST_REDSTONE; - break; - case EAST: - p = EAST_REDSTONE; - break; - default: - throw new IllegalStateException("Unexpected value: " + facing); + @Override + public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) { + Set controllers = new HashSet<>(); + + // TODO: Find a better way to do this instead of a BFS through the world + Network.getConnectedControllers(world, pos, controllers); + + System.out.println("Controllers: " + controllers); + for (BlockPos p : controllers){ + ControllerBlockEntity be = (ControllerBlockEntity)world.getBlockEntity(p); + // be.network.connectors.add(p); + Set known = new HashSet<>(); + known.addAll(be.network.cables); + known.addAll(be.network.connectors); + Network.getConnectedBlocks(world, pos, known, be.network.cables, be.network.connectors); } - return p; } public int getRedstoneOutput(Direction facing, BlockView world, BlockPos pos){ BlockState state = world.getBlockState(pos.offset(facing)); return state.getBlock().getWeakRedstonePower(state, world, pos, facing); } + + @Override + public BlockEntity createBlockEntity(BlockView view) { + return new ConnectorBlockEntity(); + } } diff --git a/src/main/java/com/martmists/ynet/blocks/ControllerBlock.java b/src/main/java/com/martmists/ynet/blocks/ControllerBlock.java index 97ef0dc..55f0772 100644 --- a/src/main/java/com/martmists/ynet/blocks/ControllerBlock.java +++ b/src/main/java/com/martmists/ynet/blocks/ControllerBlock.java @@ -1,9 +1,22 @@ package com.martmists.ynet.blocks; +import com.martmists.ynet.api.BaseProvider; import com.martmists.ynet.blockentities.ControllerBlockEntity; +import net.minecraft.block.BlockState; import net.minecraft.block.BlockWithEntity; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.BlockView; +import net.minecraft.world.World; + +import java.util.List; +import java.util.Set; public class ControllerBlock extends BlockWithEntity { public ControllerBlock(Settings settings) { @@ -14,4 +27,21 @@ public class ControllerBlock extends BlockWithEntity { public BlockEntity createBlockEntity(BlockView view) { return new ControllerBlockEntity(); } + + @Override + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + if (world.isClient) { + // Open screen + // for now, print all connected providers + Set providers = ((ControllerBlockEntity)world.getBlockEntity(pos)).network.getProviders(world); + System.out.println("Start of list"); + for (BlockPos p : providers) { + // TODO: Able to find providers that are no longer connected (e.g. cable was broken) + System.out.println("Provider found at " + p + ": " + world.getBlockState(p).getBlock()); + } + System.out.println("End of list"); + } + + return ActionResult.SUCCESS; + } } diff --git a/src/main/java/com/martmists/ynet/event/ProviderTickCallback.java b/src/main/java/com/martmists/ynet/event/ProviderTickCallback.java index 14def8e..6215202 100644 --- a/src/main/java/com/martmists/ynet/event/ProviderTickCallback.java +++ b/src/main/java/com/martmists/ynet/event/ProviderTickCallback.java @@ -2,15 +2,17 @@ package com.martmists.ynet.event; import com.martmists.ynet.api.BaseProvider; import com.martmists.ynet.blockentities.ControllerBlockEntity; +import com.martmists.ynet.network.ConnectorConfiguration; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.util.ActionResult; +import net.minecraft.util.math.BlockPos; import java.lang.reflect.Array; import java.util.Arrays; +import java.util.Map; +import java.util.Set; public interface ProviderTickCallback { - // DO NOT OVERRIDE - default T[] createArray(Class clazz) { return (T[])Array.newInstance(clazz, 0); } - ActionResult interact(T[] listeners, ControllerBlockEntity be); + void interact(Set listeners, ControllerBlockEntity be); } diff --git a/src/main/java/com/martmists/ynet/mixin/accessors/InventoryStacksAccessor.java b/src/main/java/com/martmists/ynet/mixin/accessors/InventoryStacksAccessor.java index bf1f87a..e08a250 100644 --- a/src/main/java/com/martmists/ynet/mixin/accessors/InventoryStacksAccessor.java +++ b/src/main/java/com/martmists/ynet/mixin/accessors/InventoryStacksAccessor.java @@ -2,13 +2,12 @@ package com.martmists.ynet.mixin.accessors; import net.minecraft.block.entity.LootableContainerBlockEntity; import net.minecraft.item.ItemStack; +import net.minecraft.util.DefaultedList; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; -import java.util.List; - @Mixin(LootableContainerBlockEntity.class) public interface InventoryStacksAccessor { - @Invoker - List callGetInvStacks(); + @Invoker("getInvStackList") + DefaultedList callGetInvStackList(); } diff --git a/src/main/java/com/martmists/ynet/mixin/providers/energy/PowerAcceptorMixin.java b/src/main/java/com/martmists/ynet/mixin/providers/energy/PowerAcceptorMixin.java index 8ab2e74..1a31662 100644 --- a/src/main/java/com/martmists/ynet/mixin/providers/energy/PowerAcceptorMixin.java +++ b/src/main/java/com/martmists/ynet/mixin/providers/energy/PowerAcceptorMixin.java @@ -8,11 +8,12 @@ import org.spongepowered.asm.mixin.Mixin; import reborncore.common.powerSystem.PowerAcceptorBlockEntity; import team.reborn.energy.EnergySide; import techreborn.blocks.GenericMachineBlock; +import techreborn.blocks.generator.BlockSolarPanel; import techreborn.blocks.generator.GenericGeneratorBlock; import techreborn.blocks.storage.energy.EnergyStorageBlock; -@Mixin({GenericMachineBlock.class, GenericGeneratorBlock.class, EnergyStorageBlock.class}) +@Mixin({GenericMachineBlock.class, GenericGeneratorBlock.class, EnergyStorageBlock.class, BlockSolarPanel.class}) public class PowerAcceptorMixin implements EnergyProvider { @Override public double getEnergyInputLimit(BlockView world, BlockPos pos) { diff --git a/src/main/java/com/martmists/ynet/mixin/providers/item/LootableContainerBlockMixin.java b/src/main/java/com/martmists/ynet/mixin/providers/item/LootableContainerBlockMixin.java index 6d42f71..9207196 100644 --- a/src/main/java/com/martmists/ynet/mixin/providers/item/LootableContainerBlockMixin.java +++ b/src/main/java/com/martmists/ynet/mixin/providers/item/LootableContainerBlockMixin.java @@ -19,7 +19,7 @@ public abstract class LootableContainerBlockMixin implements ItemProvider { @Override public int getItemInputCount(BlockView world, BlockPos pos, ItemStack itemStack) { - List stacks = ((InventoryStacksAccessor)getBlockEntity(world, pos)).callGetInvStacks(); + List stacks = ((InventoryStacksAccessor)getBlockEntity(world, pos)).callGetInvStackList(); if (stacks.stream().anyMatch(ItemStack::isEmpty)) { return itemStack.getMaxCount(); } @@ -34,7 +34,7 @@ public abstract class LootableContainerBlockMixin implements ItemProvider { @Override public void inputItem(BlockView world, BlockPos pos, ItemStack itemStack) { - List stacks = ((InventoryStacksAccessor)getBlockEntity(world, pos)).callGetInvStacks(); + List stacks = ((InventoryStacksAccessor)getBlockEntity(world, pos)).callGetInvStackList(); int inputCount = itemStack.getCount(); for (ItemStack stack : stacks) { if (stack.getItem() == itemStack.getItem()){ @@ -61,12 +61,12 @@ public abstract class LootableContainerBlockMixin implements ItemProvider { @Override public ItemStack[] getItemOutputStacks(BlockView world, BlockPos pos) { - return ((InventoryStacksAccessor)getBlockEntity(world, pos)).callGetInvStacks().stream().filter(stack -> !stack.isEmpty()).toArray(ItemStack[]::new); + return ((InventoryStacksAccessor)getBlockEntity(world, pos)).callGetInvStackList().stream().filter(stack -> !stack.isEmpty()).toArray(ItemStack[]::new); } @Override public void outputItem(BlockView world, BlockPos pos, ItemStack itemStack) { - List stacks = ((InventoryStacksAccessor)getBlockEntity(world, pos)).callGetInvStacks(); + List stacks = ((InventoryStacksAccessor)getBlockEntity(world, pos)).callGetInvStackList(); int outputCount = itemStack.getCount(); int i = 0; for (ItemStack stack : stacks){ diff --git a/src/main/java/com/martmists/ynet/network/Channel.java b/src/main/java/com/martmists/ynet/network/Channel.java new file mode 100644 index 0000000..c550ff9 --- /dev/null +++ b/src/main/java/com/martmists/ynet/network/Channel.java @@ -0,0 +1,10 @@ +package com.martmists.ynet.network; + +import com.martmists.ynet.api.BaseProvider; + +import java.util.Set; + +public class Channel { + public Class providerType; + public Set connectorSettings; +} diff --git a/src/main/java/com/martmists/ynet/network/ConnectorConfiguration.java b/src/main/java/com/martmists/ynet/network/ConnectorConfiguration.java new file mode 100644 index 0000000..1125020 --- /dev/null +++ b/src/main/java/com/martmists/ynet/network/ConnectorConfiguration.java @@ -0,0 +1,17 @@ +package com.martmists.ynet.network; + +import net.minecraft.item.Item; +import net.minecraft.util.math.BlockPos; + +public class ConnectorConfiguration { + public State state = State.DISABLED; + public BlockPos providerPos; + public int priority; + public Item[] filter; + + public static enum State { + DISABLED, + INPUT, + OUTPUT + } +} diff --git a/src/main/java/com/martmists/ynet/network/Network.java b/src/main/java/com/martmists/ynet/network/Network.java new file mode 100644 index 0000000..7fab994 --- /dev/null +++ b/src/main/java/com/martmists/ynet/network/Network.java @@ -0,0 +1,119 @@ +package com.martmists.ynet.network; + +import com.martmists.ynet.YNetMod; +import com.martmists.ynet.api.BaseProvider; +import com.martmists.ynet.blockentities.ControllerBlockEntity; +import net.minecraft.block.Block; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.BlockView; + +import java.util.*; + +public class Network { + private BlockPos controller; + public Set cables; + public Set connectors; + + public void reloadAllNodes(BlockView world) { + cables = new HashSet<>(); + connectors = new HashSet<>(); + ControllerBlockEntity be = ((ControllerBlockEntity)world.getBlockEntity(controller)); + getConnectedBlocks(be.getWorld(), controller, cables, connectors); + } + + public static void getConnectedBlocks(BlockView world, BlockPos origin, Set cables, Set connectors) { + getConnectedBlocks(world, origin, new HashSet<>(), cables, connectors); + } + + public static void getConnectedBlocks(BlockView world, BlockPos origin, Set exclude, Set cables, Set connectors) { + ArrayDeque toSearch = new ArrayDeque<>(); + toSearch.push(origin); + exclude.add(origin); + // Search origin first + Block bo = world.getBlockState(origin).getBlock(); + if (bo == YNetMod.CABLE) { + cables.add(origin); + } else if (bo == YNetMod.CONNECTOR) { + connectors.add(origin); + } + + // Search connected + while (!toSearch.isEmpty()){ + BlockPos p = toSearch.removeFirst(); + for (BlockPos p2 : Arrays.asList(p.up(), p.down(), p.north(), p.south(), p.east(), p.west())) { + if (exclude.contains(p2)) { + continue; + } + exclude.add(p2); + Block b = world.getBlockState(p2).getBlock(); + if (b == YNetMod.CABLE) { + toSearch.add(p2); + cables.add(p2); + } else if (b == YNetMod.CONNECTOR) { + toSearch.add(p2); + connectors.add(p2); + } + } + } + } + + public static void getConnectedControllers(BlockView world, BlockPos origin, Set controllers) { + ArrayDeque toSearch = new ArrayDeque<>(); + toSearch.push(origin); + List searched = new ArrayList<>(); + while (!toSearch.isEmpty()){ + BlockPos p = toSearch.removeFirst(); + for (BlockPos p2 : Arrays.asList(p.up(), p.down(), p.north(), p.south(), p.east(), p.west())) { + if (searched.contains(p2)) { + continue; + } + searched.add(p2); + Block b = world.getBlockState(p2).getBlock(); + if (b == YNetMod.CABLE || b == YNetMod.CONNECTOR) { + toSearch.add(p2); + } else if (b == YNetMod.CONTROLLER) { + controllers.add(p2); + } + } + } + } + + public void setController(BlockPos pos) { + controller = pos; + } + + public Set getProviders(BlockView world) { + return getProviders(world, BaseProvider.class); + } + + public Set getProviders(BlockView world, Class type) { + Set providers = new HashSet<>(); + connectors.forEach((c) -> { + for (BlockPos p : Arrays.asList(c.up(), c.down(), c.north(), c.south(), c.east(), c.west())) { + Block b = world.getBlockState(p).getBlock(); + Set> providerTypes = new HashSet<>(); + findProviderTypes(b.getClass(), providerTypes); + if (providerTypes.contains(type) || (type == BaseProvider.class && b instanceof BaseProvider)) { + providers.add(p); + } + } + }); + return providers; + } + + + // Ugly hack by Pyrofab + private static Map, Set>> tMap = new HashMap<>(); + private static void findProviderTypes(Class cls, Set> ret) { + tMap.putIfAbsent(cls, ret); + if (cls != Object.class && cls != null) { + if (BaseProvider.class.isAssignableFrom(cls)) { + ret.add((Class) cls); + } + findProviderTypes(cls.getSuperclass(), ret); + for (Class itf : cls.getInterfaces()) { + findProviderTypes(itf, ret); + } + } + } +} diff --git a/src/main/resources/assets/ynet/blockstates/connector.json b/src/main/resources/assets/ynet/blockstates/connector.json new file mode 100644 index 0000000..00225bd --- /dev/null +++ b/src/main/resources/assets/ynet/blockstates/connector.json @@ -0,0 +1,119 @@ +{ + "multipart": [ + { + "apply": { + "model": "ynet:block/cable" + } + }, + { + "when": { + "north": true + }, + "apply": { + "model": "ynet:block/connector", + "x": 270 + } + }, + { + "when": { + "east": true + }, + "apply": { + "model": "ynet:block/connector", + "x": 90, + "y": 270 + } + }, + { + "when": { + "south": true + }, + "apply": { + "model": "ynet:block/connector", + "x": 90 + } + }, + { + "when": { + "west": true + }, + "apply": { + "model": "ynet:block/connector", + "x": 90, + "y": 90 + } + }, + { + "when": { + "up": true + }, + "apply": { + "model": "ynet:block/connector", + "x": 180 + } + }, + { + "when": { + "down": true + }, + "apply": { + "model": "ynet:block/connector" + } + }, + { + "when": { + "north_cable": true + }, + "apply": { + "model": "ynet:block/cable_side", + "x": 270 + } + }, + { + "when": { + "east_cable": true + }, + "apply": { + "model": "ynet:block/cable_side", + "x": 90, + "y": 270 + } + }, + { + "when": { + "south_cable": true + }, + "apply": { + "model": "ynet:block/cable_side", + "x": 90 + } + }, + { + "when": { + "west_cable": true + }, + "apply": { + "model": "ynet:block/cable_side", + "x": 90, + "y": 90 + } + }, + { + "when": { + "up_cable": true + }, + "apply": { + "model": "ynet:block/cable_side", + "x": 180 + } + }, + { + "when": { + "down_cable": true + }, + "apply": { + "model": "ynet:block/cable_side" + } + } + ] +} diff --git a/src/main/resources/assets/ynet/models/block/connector.json b/src/main/resources/assets/ynet/models/block/connector.json new file mode 100644 index 0000000..62cfdfc --- /dev/null +++ b/src/main/resources/assets/ynet/models/block/connector.json @@ -0,0 +1,37 @@ +{ + "credit": "Made with Blockbench", + "ambientocclusion": false, + "textures": { + "0": "ynet:block/pipe", + "1": "ynet:block/connector", + "particle": "ynet:block/pipe" + }, + "elements": [ + { + "name": "pipe_side", + "from": [5, 1, 5], + "to": [11, 5, 11], + "faces": { + "north": {"uv": [0, 0, 6, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 6, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 6, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 6, 4], "texture": "#0"}, + "up": {"uv": [0, 0, 6, 6], "texture": "#0"}, + "down": {"uv": [0, 0, 6, 6], "texture": "#0"} + } + }, + { + "name": "connector", + "from": [3, 0, 3], + "to": [13, 1, 13], + "faces": { + "north": {"uv": [0, 0, 10, 1], "texture": "#1"}, + "east": {"uv": [0, 0, 10, 1], "texture": "#1"}, + "south": {"uv": [0, 0, 10, 1], "texture": "#1"}, + "west": {"uv": [0, 0, 10, 1], "texture": "#1"}, + "up": {"uv": [0, 0, 10, 10], "texture": "#1"}, + "down": {"uv": [0, 0, 10, 10], "texture": "#1"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/ynet/textures/block/connector.png b/src/main/resources/assets/ynet/textures/block/connector.png new file mode 100644 index 0000000000000000000000000000000000000000..83be50e3a282423c9a05597715bfe9b5ea78438c GIT binary patch literal 128 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`?w&4=Ar}70I%{)(oOfV(k+tgh zsxHA4hw@_PIOT>c2@WZSpcdW+9(mJ-xWop1InHBDf-gDBt$y&c9Fb`7=6$?^kw>JR ak>UL9%!}No@?HRqWbkzLb6Mw<&;$Tf-zBF2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/ynet/textures/block/pipe.png b/src/main/resources/assets/ynet/textures/block/pipe.png index 77f4768434fdd8c3adb4e6ef171c7603d5633ddc..a7bb7cd228152be719b03a70138868153442acaf 100644 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^Y#_`5A|IT2?*XJZ3p^r=85p=bL736}