Add redstone interface card.

This commit is contained in:
Florian Nücke
2020-12-29 18:09:44 +01:00
parent 8c7c314403
commit 1f16bafe4e
8 changed files with 200 additions and 0 deletions

View File

@@ -23,6 +23,7 @@ public final class Constants {
public static final String FLASH_MEMORY_ITEM_NAME = "flash_memory";
public static final String MEMORY_ITEM_NAME = "memory";
public static final String HARD_DRIVE_ITEM_NAME = "hard_drive";
public static final String REDSTONE_INTERFACE_CARD_NAME = "redstone_interface_card";
///////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,165 @@
package li.cil.oc2.common.bus.device.item;
import li.cil.oc2.api.bus.device.ItemDevice;
import li.cil.oc2.api.bus.device.capabilities.RedstoneEmitter;
import li.cil.oc2.api.bus.device.object.Callback;
import li.cil.oc2.api.bus.device.object.ObjectDevice;
import li.cil.oc2.api.bus.device.rpc.RPCDevice;
import li.cil.oc2.api.bus.device.rpc.RPCMethod;
import li.cil.oc2.common.bus.device.util.IdentityProxy;
import li.cil.oc2.common.capabilities.Capabilities;
import li.cil.oc2.common.util.HorizontalBlockUtils;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Objects;
public final class RedstoneInterfaceCardItemDevice extends IdentityProxy<ItemStack> implements RPCDevice, ItemDevice, ICapabilityProvider {
private static final int FACE_COUNT = Direction.values().length;
private static final String OUTPUT_TAG_NAME = "output";
///////////////////////////////////////////////////////////////////
private final TileEntity tileEntity;
private final ObjectDevice device;
private final RedstoneEmitter[] capabilities;
private final byte[] output = new byte[FACE_COUNT];
///////////////////////////////////////////////////////////////////
public RedstoneInterfaceCardItemDevice(final ItemStack value, final TileEntity tileEntity) {
super(value);
this.tileEntity = tileEntity;
this.device = new ObjectDevice(this, "redstone");
capabilities = new RedstoneEmitter[FACE_COUNT];
for (int i = 0; i < FACE_COUNT; i++) {
final int indexForClosure = i;
capabilities[i] = () -> output[indexForClosure];
}
}
///////////////////////////////////////////////////////////////////
@Override
public List<String> getTypeNames() {
return device.getTypeNames();
}
@Override
public List<RPCMethod> getMethods() {
return device.getMethods();
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull final Capability<T> cap, @Nullable final Direction side) {
if (cap == Capabilities.REDSTONE_EMITTER && side != null) {
return LazyOptional.of(() -> capabilities[side.getIndex()]).cast();
}
return LazyOptional.empty();
}
@Override
public CompoundNBT serializeNBT() {
final CompoundNBT nbt = new CompoundNBT();
nbt.putByteArray(OUTPUT_TAG_NAME, output);
return nbt;
}
@Override
public void deserializeNBT(final CompoundNBT nbt) {
final byte[] serializedOutput = nbt.getByteArray(OUTPUT_TAG_NAME);
System.arraycopy(serializedOutput, 0, output, 0, Math.min(serializedOutput.length, output.length));
}
///////////////////////////////////////////////////////////////////
@Callback(synchronize = false)
public int getRedstoneOutput(final Direction side) {
return output[side.getIndex()];
}
@Callback
public void setRedstoneOutput(final Direction side, final int value) {
final byte clampedValue = (byte) MathHelper.clamp(value, 0, 15);
if (clampedValue == output[side.getIndex()]) {
return;
}
output[side.getIndex()] = clampedValue;
final Direction direction = HorizontalBlockUtils.toGlobal(tileEntity.getBlockState(), side);
if (direction != null) {
notifyNeighbors(direction);
}
}
@Callback
public int getRedstoneInput(final Direction side) {
final World world = tileEntity.getWorld();
if (world == null) {
return 0;
}
final BlockPos pos = tileEntity.getPos();
final Direction direction = HorizontalBlockUtils.toGlobal(tileEntity.getBlockState(), side);
assert direction != null;
final BlockPos neighborPos = pos.offset(direction);
final ChunkPos chunkPos = new ChunkPos(neighborPos.getX(), neighborPos.getZ());
if (!world.chunkExists(chunkPos.x, chunkPos.z)) {
return 0;
}
return world.getRedstonePower(neighborPos, direction);
}
///////////////////////////////////////////////////////////////////
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
final RedstoneInterfaceCardItemDevice that = (RedstoneInterfaceCardItemDevice) o;
return tileEntity.equals(that.tileEntity);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), tileEntity);
}
///////////////////////////////////////////////////////////////////
private void notifyNeighbors(final Direction direction) {
final World world = tileEntity.getWorld();
if (world == null) {
return;
}
final BlockPos pos = tileEntity.getPos();
final BlockState state = tileEntity.getBlockState();
final Block block = state.getBlock();
world.notifyNeighborsOfStateChange(pos, block);
world.notifyNeighborsOfStateChange(pos.offset(direction), block);
}
}

View File

@@ -0,0 +1,23 @@
package li.cil.oc2.common.bus.device.provider.item;
import li.cil.oc2.api.bus.device.ItemDevice;
import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery;
import li.cil.oc2.common.bus.device.item.RedstoneInterfaceCardItemDevice;
import li.cil.oc2.common.bus.device.provider.util.AbstractItemDeviceProvider;
import li.cil.oc2.common.init.Items;
import java.util.Optional;
public final class RedstoneInterfaceCardItemDeviceProvider extends AbstractItemDeviceProvider {
public RedstoneInterfaceCardItemDeviceProvider() {
super(Items.REDSTONE_INTERFACE_CARD_ITEM);
}
///////////////////////////////////////////////////////////////////
@Override
protected Optional<ItemDevice> getItemDevice(final ItemDeviceQuery query) {
return query.getContainerTileEntity().map(tileEntity ->
new RedstoneInterfaceCardItemDevice(query.getItemStack(), tileEntity));
}
}

View File

@@ -30,6 +30,7 @@ public final class Items {
public static final RegistryObject<Item> MEMORY_ITEM = register(Constants.MEMORY_ITEM_NAME, MemoryItem::new, new Item.Properties());
public static final RegistryObject<Item> HARD_DRIVE_ITEM = register(Constants.HARD_DRIVE_ITEM_NAME, HardDriveItem::new, new Item.Properties());
public static final RegistryObject<Item> FLASH_MEMORY_ITEM = register(Constants.FLASH_MEMORY_ITEM_NAME, FlashMemoryItem::new, new Item.Properties());
public static final RegistryObject<Item> REDSTONE_INTERFACE_CARD_ITEM = register(Constants.REDSTONE_INTERFACE_CARD_NAME);
///////////////////////////////////////////////////////////////////

View File

@@ -7,6 +7,7 @@ import li.cil.oc2.common.bus.device.provider.block.*;
import li.cil.oc2.common.bus.device.provider.item.FlashMemoryItemDeviceProvider;
import li.cil.oc2.common.bus.device.provider.item.HardDriveItemDeviceProvider;
import li.cil.oc2.common.bus.device.provider.item.MemoryItemDeviceProvider;
import li.cil.oc2.common.bus.device.provider.item.RedstoneInterfaceCardItemDeviceProvider;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.IForgeRegistry;
@@ -36,6 +37,7 @@ public final class Providers {
ITEM_DEVICE_PROVIDERS.register("item_memory", MemoryItemDeviceProvider::new);
ITEM_DEVICE_PROVIDERS.register("item_hard_drive", HardDriveItemDeviceProvider::new);
ITEM_DEVICE_PROVIDERS.register("item_flash_memory", FlashMemoryItemDeviceProvider::new);
ITEM_DEVICE_PROVIDERS.register("item_redstone_interface_card", RedstoneInterfaceCardItemDeviceProvider::new);
BLOCK_DEVICE_PROVIDERS.register(FMLJavaModLoadingContext.get().getModEventBus());
ITEM_DEVICE_PROVIDERS.register(FMLJavaModLoadingContext.get().getModEventBus());

View File

@@ -43,6 +43,7 @@ public final class ItemModels extends ItemModelProvider {
.end();
simple(Items.FLASH_MEMORY_ITEM, "items/flash_memory");
simple(Items.REDSTONE_INTERFACE_CARD_ITEM, "items/redstone_interface_card");
}
private <T extends Item> ItemModelBuilder simple(final RegistryObject<T> item, final String texturePath) {

View File

@@ -11,6 +11,7 @@
"item.oc2.memory": "Memory",
"item.oc2.hard_drive": "Hard Drive",
"item.oc2.flash_memory": "Flash Memory",
"item.oc2.redstone_interface_card": "Redstone Interface Card",
"gui.oc2.computer.boot_error.unknown": "Unknown Error",
"gui.oc2.computer.boot_error.no_memory": "Insufficient Memory",

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "oc2:items/redstone_interface_card"
}
}