Browse Source

Better networking, more models & textures

master
Martmists 2 years ago
parent
commit
b895ff60e9
  1. 22
      src/main/java/com/martmists/ynet/YNetMod.java
  2. 24
      src/main/java/com/martmists/ynet/blockentities/ConnectorBlockEntity.java
  3. 79
      src/main/java/com/martmists/ynet/blockentities/ControllerBlockEntity.java
  4. 42
      src/main/java/com/martmists/ynet/blocks/CableBlock.java
  5. 150
      src/main/java/com/martmists/ynet/blocks/ConnectorBlock.java
  6. 30
      src/main/java/com/martmists/ynet/blocks/ControllerBlock.java
  7. 8
      src/main/java/com/martmists/ynet/event/ProviderTickCallback.java
  8. 7
      src/main/java/com/martmists/ynet/mixin/accessors/InventoryStacksAccessor.java
  9. 3
      src/main/java/com/martmists/ynet/mixin/providers/energy/PowerAcceptorMixin.java
  10. 8
      src/main/java/com/martmists/ynet/mixin/providers/item/LootableContainerBlockMixin.java
  11. 10
      src/main/java/com/martmists/ynet/network/Channel.java
  12. 17
      src/main/java/com/martmists/ynet/network/ConnectorConfiguration.java
  13. 119
      src/main/java/com/martmists/ynet/network/Network.java
  14. 119
      src/main/resources/assets/ynet/blockstates/connector.json
  15. 37
      src/main/resources/assets/ynet/models/block/connector.json
  16. BIN
      src/main/resources/assets/ynet/textures/block/connector.png
  17. BIN
      src/main/resources/assets/ynet/textures/block/pipe.png

22
src/main/java/com/martmists/ynet/YNetMod.java

@ -3,11 +3,13 @@ package com.martmists.ynet; @@ -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; @@ -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 { @@ -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<ConnectorBlockEntity> 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<ControllerBlockEntity> CONTROLLER_BE = Registry.register(
Registry.BLOCK_ENTITY_TYPE,
@ -49,17 +59,19 @@ public class YNetMod implements ModInitializer { @@ -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<ConnectorConfiguration> takeEnergy = listeners.stream().filter(config -> config.state == ConnectorConfiguration.State.INPUT).collect(Collectors.toSet());
Set<ConnectorConfiguration> giveEnergy = listeners.stream().filter(config -> config.state == ConnectorConfiguration.State.OUTPUT).collect(Collectors.toSet());
});
// TODO:
// - Add support for configuring redstone signals on connectors

24
src/main/java/com/martmists/ynet/blockentities/ConnectorBlockEntity.java

@ -0,0 +1,24 @@ @@ -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<Direction, Integer> 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);
}
}

79
src/main/java/com/martmists/ynet/blockentities/ControllerBlockEntity.java

@ -5,6 +5,8 @@ import com.martmists.ynet.api.BaseProvider; @@ -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.*; @@ -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<BlockPos> toSearch = new ArrayDeque<BlockPos>();
toSearch.push(pos);
List<BlockPos> searched = new ArrayList<>();
searched.add(pos);
public void updateNetwork() {
network.reloadAllNodes(world);
}
private List<BlockPos> getConnectedProviders(Set<BlockPos> connectors) {
List<BlockPos> 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<Class<? extends BaseProvider>, List<BaseProvider>> blockMap = new HashMap<>();
for (Block b : blocks) {
Class<?> bClass = b.getClass();
if (!tMap.containsKey(bClass)){
Set<Class<? extends BaseProvider>> set = new HashSet<>();
findProviderTypes(bClass, set);
tMap.put(bClass, set);
}
for (Class<? extends BaseProvider> 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<? extends BaseProvider> clazz : blockMap.keySet()) {
dispatch(clazz, blockMap.get(clazz));
}
}
private <P extends BaseProvider> void dispatch(Class<? extends BaseProvider> clazz, List<P> blockMap) {
ProviderTickCallback<P> provider = (ProviderTickCallback<P>) YNetMod.PROVIDERS.get(clazz);
provider.interact(blockMap.toArray(provider.createArray((Class<P>) clazz)), this);
}
// Ugly hack by Pyrofab
private static Map<Class<?>, Set<Class<? extends BaseProvider>>> tMap = new HashMap<>();
private static void findProviderTypes(Class<?> cls, Set<Class<? extends BaseProvider>> ret) {
tMap.putIfAbsent(cls, ret);
if (cls != Object.class) {
if (BaseProvider.class.isAssignableFrom(cls)) {
ret.add((Class<? extends BaseProvider>) cls);
}
findProviderTypes(cls.getSuperclass(), ret);
for (Class<?> itf : cls.getInterfaces()) {
findProviderTypes(itf, ret);
Set<BlockPos> blocks = network.getProviders(world);
for (Channel ch : channels) {
if (ch != null) {
YNetMod.PROVIDERS.get(ch.providerType).interact(ch.connectorSettings, this);
}
}
}

42
src/main/java/com/martmists/ynet/blocks/CableBlock.java

@ -2,17 +2,26 @@ package com.martmists.ynet.blocks; @@ -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 { @@ -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<BlockPos> 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<BlockPos> 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<BlockPos> 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();

150
src/main/java/com/martmists/ynet/blocks/ConnectorBlock.java

@ -2,12 +2,15 @@ package com.martmists.ynet.blocks; @@ -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; @@ -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<Direction, BooleanProperty> 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 { @@ -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<Block, BlockState> 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 { @@ -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 extends BaseProvider> T[] getProviders(BlockView world, BlockPos pos) {
List<T> 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 { @@ -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 { @@ -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<BlockPos> 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<BlockPos> 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<BlockPos> 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();
}
}

30
src/main/java/com/martmists/ynet/blocks/ControllerBlock.java

@ -1,9 +1,22 @@ @@ -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 { @@ -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<BlockPos> 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;
}
}

8
src/main/java/com/martmists/ynet/event/ProviderTickCallback.java

@ -2,15 +2,17 @@ package com.martmists.ynet.event; @@ -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<T extends BaseProvider> {
// DO NOT OVERRIDE
default T[] createArray(Class<T> clazz) { return (T[])Array.newInstance(clazz, 0); }
ActionResult interact(T[] listeners, ControllerBlockEntity be);
void interact(Set<ConnectorConfiguration> listeners, ControllerBlockEntity be);
}

7
src/main/java/com/martmists/ynet/mixin/accessors/InventoryStacksAccessor.java

@ -2,13 +2,12 @@ package com.martmists.ynet.mixin.accessors; @@ -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<ItemStack> callGetInvStacks();
@Invoker("getInvStackList")
DefaultedList<ItemStack> callGetInvStackList();
}

3
src/main/java/com/martmists/ynet/mixin/providers/energy/PowerAcceptorMixin.java

@ -8,11 +8,12 @@ import org.spongepowered.asm.mixin.Mixin; @@ -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) {

8
src/main/java/com/martmists/ynet/mixin/providers/item/LootableContainerBlockMixin.java

@ -19,7 +19,7 @@ public abstract class LootableContainerBlockMixin implements ItemProvider { @@ -19,7 +19,7 @@ public abstract class LootableContainerBlockMixin implements ItemProvider {
@Override
public int getItemInputCount(BlockView world, BlockPos pos, ItemStack itemStack) {
List<ItemStack> stacks = ((InventoryStacksAccessor)getBlockEntity(world, pos)).callGetInvStacks();
List<ItemStack> 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 { @@ -34,7 +34,7 @@ public abstract class LootableContainerBlockMixin implements ItemProvider {
@Override
public void inputItem(BlockView world, BlockPos pos, ItemStack itemStack) {
List<ItemStack> stacks = ((InventoryStacksAccessor)getBlockEntity(world, pos)).callGetInvStacks();
List<ItemStack> 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 { @@ -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<ItemStack> stacks = ((InventoryStacksAccessor)getBlockEntity(world, pos)).callGetInvStacks();
List<ItemStack> stacks = ((InventoryStacksAccessor)getBlockEntity(world, pos)).callGetInvStackList();
int outputCount = itemStack.getCount();
int i = 0;
for (ItemStack stack : stacks){

10
src/main/java/com/martmists/ynet/network/Channel.java

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
package com.martmists.ynet.network;
import com.martmists.ynet.api.BaseProvider;
import java.util.Set;
public class Channel {
public Class<? extends BaseProvider> providerType;
public Set<ConnectorConfiguration> connectorSettings;
}

17
src/main/java/com/martmists/ynet/network/ConnectorConfiguration.java

@ -0,0 +1,17 @@ @@ -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
}
}

119
src/main/java/com/martmists/ynet/network/Network.java

@ -0,0 +1,119 @@ @@ -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<BlockPos> cables;
public Set<BlockPos> 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<BlockPos> cables, Set<BlockPos> connectors) {
getConnectedBlocks(world, origin, new HashSet<>(), cables, connectors);
}
public static void getConnectedBlocks(BlockView world, BlockPos origin, Set<BlockPos> exclude, Set<BlockPos> cables, Set<BlockPos> connectors) {
ArrayDeque<BlockPos> 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<BlockPos> controllers) {
ArrayDeque<BlockPos> toSearch = new ArrayDeque<>();
toSearch.push(origin);
List<BlockPos> 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<BlockPos> getProviders(BlockView world) {
return getProviders(world, BaseProvider.class);
}
public Set<BlockPos> getProviders(BlockView world, Class<BaseProvider> type) {
Set<BlockPos> 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<Class<? extends BaseProvider>> 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<Class<?>, Set<Class<? extends BaseProvider>>> tMap = new HashMap<>();
private static void findProviderTypes(Class<?> cls, Set<Class<? extends BaseProvider>> ret) {
tMap.putIfAbsent(cls, ret);
if (cls != Object.class && cls != null) {
if (BaseProvider.class.isAssignableFrom(cls)) {
ret.add((Class<? extends BaseProvider>) cls);
}
findProviderTypes(cls.getSuperclass(), ret);
for (Class<?> itf : cls.getInterfaces()) {
findProviderTypes(itf, ret);
}
}
}
}

119
src/main/resources/assets/ynet/blockstates/connector.json

@ -0,0 +1,119 @@ @@ -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"
}
}
]
}

37
src/main/resources/assets/ynet/models/block/connector.json

@ -0,0 +1,37 @@ @@ -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"}
}
}
]
}

BIN
src/main/resources/assets/ynet/textures/block/connector.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

BIN
src/main/resources/assets/ynet/textures/block/pipe.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 B

After

Width:  |  Height:  |  Size: 99 B

Loading…
Cancel
Save