diff --git a/src/main/java/li/cil/oc2/api/bus/device/DeviceTypes.java b/src/main/java/li/cil/oc2/api/bus/device/DeviceTypes.java index bf72791a..b4d1f2a8 100644 --- a/src/main/java/li/cil/oc2/api/bus/device/DeviceTypes.java +++ b/src/main/java/li/cil/oc2/api/bus/device/DeviceTypes.java @@ -12,4 +12,5 @@ public final class DeviceTypes { @ObjectHolder("hard_drive") public static DeviceType HARD_DRIVE = null; @ObjectHolder("flash_memory") public static DeviceType FLASH_MEMORY = null; @ObjectHolder("card") public static DeviceType CARD = null; + @ObjectHolder("robot_module") public static DeviceType ROBOT_MODULE = null; } diff --git a/src/main/java/li/cil/oc2/common/bus/device/DeviceTypes.java b/src/main/java/li/cil/oc2/common/bus/device/DeviceTypes.java index 2364c5bf..b77d964e 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/DeviceTypes.java +++ b/src/main/java/li/cil/oc2/common/bus/device/DeviceTypes.java @@ -26,6 +26,7 @@ public final class DeviceTypes { register("hard_drive"); register("flash_memory"); register("card"); + register("robot_module"); DEVICE_TYPES.register(FMLJavaModLoadingContext.get().getModEventBus()); } diff --git a/src/main/java/li/cil/oc2/common/entity/RobotEntity.java b/src/main/java/li/cil/oc2/common/entity/RobotEntity.java index 78fde973..d340e363 100644 --- a/src/main/java/li/cil/oc2/common/entity/RobotEntity.java +++ b/src/main/java/li/cil/oc2/common/entity/RobotEntity.java @@ -2,6 +2,7 @@ package li.cil.oc2.common.entity; import li.cil.oc2.api.bus.DeviceBusElement; import li.cil.oc2.api.bus.device.Device; +import li.cil.oc2.api.bus.device.DeviceTypes; 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.object.Parameter; @@ -71,7 +72,7 @@ public final class RobotEntity extends Entity { private static final int MEMORY_SLOTS = 4; private static final int HARD_DRIVE_SLOTS = 2; private static final int FLASH_MEMORY_SLOTS = 1; - private static final int CARD_SLOTS = 2; + private static final int MODULE_SLOTS = 4; /////////////////////////////////////////////////////////////////// @@ -483,7 +484,12 @@ public final class RobotEntity extends Entity { private final class RobotItemStackHandlers extends AbstractVirtualMachineItemStackHandlers { public RobotItemStackHandlers() { - super(MEMORY_SLOTS, HARD_DRIVE_SLOTS, FLASH_MEMORY_SLOTS, CARD_SLOTS); + super( + GroupDefinition.of(DeviceTypes.MEMORY, MEMORY_SLOTS), + GroupDefinition.of(DeviceTypes.HARD_DRIVE, HARD_DRIVE_SLOTS), + GroupDefinition.of(DeviceTypes.FLASH_MEMORY, FLASH_MEMORY_SLOTS), + GroupDefinition.of(DeviceTypes.ROBOT_MODULE, MODULE_SLOTS) + ); } @Override diff --git a/src/main/java/li/cil/oc2/common/item/ItemGroup.java b/src/main/java/li/cil/oc2/common/item/ItemGroup.java index ef4a796b..8326c618 100644 --- a/src/main/java/li/cil/oc2/common/item/ItemGroup.java +++ b/src/main/java/li/cil/oc2/common/item/ItemGroup.java @@ -1,6 +1,7 @@ package li.cil.oc2.common.item; import li.cil.oc2.api.API; +import li.cil.oc2.api.bus.device.DeviceTypes; import li.cil.oc2.common.Constants; import li.cil.oc2.common.bus.device.data.BaseBlockDevices; import li.cil.oc2.common.bus.device.data.Firmwares; @@ -46,18 +47,18 @@ public final class ItemGroup { final ItemStack computer = new ItemStack(Items.COMPUTER_ITEM.get()); final CompoundNBT computerItems = ItemStackUtils.getOrCreateTileEntityInventoryTag(computer); - computerItems.put(AbstractVirtualMachineItemStackHandlers.MEMORY_TAG_NAME, makeInventoryTag( + computerItems.put(DeviceTypes.MEMORY.getRegistryName().toString(), makeInventoryTag( MemoryItem.withCapacity(8 * Constants.MEGABYTE), MemoryItem.withCapacity(8 * Constants.MEGABYTE), MemoryItem.withCapacity(8 * Constants.MEGABYTE) )); - computerItems.put(AbstractVirtualMachineItemStackHandlers.HARD_DRIVE_TAG_NAME, makeInventoryTag( + computerItems.put(DeviceTypes.HARD_DRIVE.getRegistryName().toString(), makeInventoryTag( HardDriveItem.withBase(BaseBlockDevices.BUILDROOT.get()) )); - computerItems.put(AbstractVirtualMachineItemStackHandlers.FLASH_MEMORY_TAG_NAME, makeInventoryTag( + computerItems.put(DeviceTypes.FLASH_MEMORY.getRegistryName().toString(), makeInventoryTag( FlashMemoryItem.withFirmware(Firmwares.BUILDROOT.get()) )); - computerItems.put(AbstractVirtualMachineItemStackHandlers.CARD_TAG_NAME, makeInventoryTag( + computerItems.put(DeviceTypes.CARD.getRegistryName().toString(), makeInventoryTag( new ItemStack(Items.NETWORK_INTERFACE_CARD_ITEM.get()) )); diff --git a/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java b/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java index 65f9916a..575a4457 100644 --- a/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java +++ b/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java @@ -2,6 +2,7 @@ package li.cil.oc2.common.tileentity; import li.cil.oc2.api.bus.DeviceBusElement; import li.cil.oc2.api.bus.device.Device; +import li.cil.oc2.api.bus.device.DeviceTypes; import li.cil.oc2.common.Constants; import li.cil.oc2.common.block.ComputerBlock; import li.cil.oc2.common.bus.AbstractDeviceBusController; @@ -225,7 +226,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic @Override protected void collectCapabilities(final CapabilityCollector collector, @Nullable final Direction direction) { - collector.offer(Capabilities.ITEM_HANDLER, items.itemHandlers); + collector.offer(Capabilities.ITEM_HANDLER, items.combinedItemHandlers); collector.offer(Capabilities.DEVICE_BUS_ELEMENT, busElement); } @@ -262,7 +263,12 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic private final class ComputerItemStackHandlers extends AbstractVirtualMachineItemStackHandlers { public ComputerItemStackHandlers() { - super(MEMORY_SLOTS, HARD_DRIVE_SLOTS, FLASH_MEMORY_SLOTS, CARD_SLOTS); + super( + GroupDefinition.of(DeviceTypes.MEMORY, MEMORY_SLOTS), + GroupDefinition.of(DeviceTypes.HARD_DRIVE, HARD_DRIVE_SLOTS), + GroupDefinition.of(DeviceTypes.FLASH_MEMORY, FLASH_MEMORY_SLOTS), + GroupDefinition.of(DeviceTypes.CARD, CARD_SLOTS) + ); } @Override diff --git a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java b/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java index c5fde87d..18a8524b 100644 --- a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java +++ b/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java @@ -15,75 +15,77 @@ import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.text.ITextComponent; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.wrapper.CombinedInvWrapper; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.RegistryManager; import java.util.*; import java.util.function.Function; +import java.util.stream.Collectors; public abstract class AbstractVirtualMachineItemStackHandlers implements VirtualMachineItemStackHandlers { + public static final class GroupDefinition { + public final DeviceType deviceType; + public final int count; + + public static GroupDefinition of(final DeviceType deviceType, final int count) { + return new GroupDefinition(deviceType, count); + } + + private GroupDefinition(final DeviceType deviceType, final int count) { + this.deviceType = deviceType; + this.count = count; + } + } + + /////////////////////////////////////////////////////////////////// + private static final long ITEM_DEVICE_BASE_ADDRESS = 0x40000000L; private static final int ITEM_DEVICE_STRIDE = 0x1000; - public static final String MEMORY_TAG_NAME = "memory"; - public static final String HARD_DRIVE_TAG_NAME = "hard_drive"; - public static final String FLASH_MEMORY_TAG_NAME = "flash_memory"; - public static final String CARD_TAG_NAME = "card"; - /////////////////////////////////////////////////////////////////// public static void addInformation(final ItemStack stack, final List tooltip) { - TooltipUtils.addInventoryInformation(stack, tooltip, - MEMORY_TAG_NAME, - HARD_DRIVE_TAG_NAME, - FLASH_MEMORY_TAG_NAME, - CARD_TAG_NAME); + final ForgeRegistry registry = RegistryManager.ACTIVE.getRegistry(DeviceType.REGISTRY); + if (registry != null) { + TooltipUtils.addInventoryInformation(stack, tooltip, + registry.getValues().stream().map(deviceType -> + deviceType.getRegistryName().toString()).toArray(String[]::new)); + } } /////////////////////////////////////////////////////////////////// public final DeviceBusElement busElement = new BusElement(); - public final DeviceItemStackHandler memoryItemHandler; - public final DeviceItemStackHandler hardDriveItemHandler; - public final DeviceItemStackHandler flashMemoryItemHandler; - public final DeviceItemStackHandler cardItemHandler; + // NB: linked hash map such that order of parameters in constructor is retained. + // This is relevant when assigning default addresses for devices. + private final LinkedHashMap itemHandlers = new LinkedHashMap<>(); - public final IItemHandler itemHandlers; + public final IItemHandler combinedItemHandlers; /////////////////////////////////////////////////////////////////// - public AbstractVirtualMachineItemStackHandlers(final int memorySlots, - final int hardDriveSlots, - final int flashMemorySlots, - final int cardSlots) { - memoryItemHandler = new ItemHandler(memorySlots, this::getDevices, DeviceTypes.MEMORY); - hardDriveItemHandler = new ItemHandler(hardDriveSlots, this::getDevices, DeviceTypes.HARD_DRIVE); - flashMemoryItemHandler = new ItemHandler(flashMemorySlots, this::getDevices, DeviceTypes.FLASH_MEMORY); - cardItemHandler = new ItemHandler(cardSlots, this::getDevices, DeviceTypes.CARD); + public AbstractVirtualMachineItemStackHandlers(final GroupDefinition... groups) { + for (final GroupDefinition group : groups) { + itemHandlers.put(group.deviceType, new ItemHandler(group.count, this::getDevices, group.deviceType)); + } - itemHandlers = new CombinedInvWrapper(memoryItemHandler, hardDriveItemHandler, flashMemoryItemHandler, cardItemHandler); + combinedItemHandlers = new CombinedInvWrapper(itemHandlers.values().toArray(new IItemHandlerModifiable[0])); } /////////////////////////////////////////////////////////////////// @Override public Optional getItemHandler(final DeviceType deviceType) { - if (deviceType == DeviceTypes.MEMORY) { - return Optional.of(memoryItemHandler); - } else if (deviceType == DeviceTypes.HARD_DRIVE) { - return Optional.of(hardDriveItemHandler); - } else if (deviceType == DeviceTypes.FLASH_MEMORY) { - return Optional.of(flashMemoryItemHandler); - } else if (deviceType == DeviceTypes.CARD) { - return Optional.of(cardItemHandler); - } - return Optional.empty(); + return Optional.ofNullable(itemHandlers.get(deviceType)); } @Override public boolean isEmpty() { - for (int slot = 0; slot < itemHandlers.getSlots(); slot++) { - if (!itemHandlers.getStackInSlot(slot).isEmpty()) { + for (int slot = 0; slot < combinedItemHandlers.getSlots(); slot++) { + if (!combinedItemHandlers.getStackInSlot(slot).isEmpty()) { return false; } } @@ -93,22 +95,23 @@ public abstract class AbstractVirtualMachineItemStackHandlers implements Virtual public OptionalLong getDefaultDeviceAddress(final VMDevice wrapper) { long address = ITEM_DEVICE_BASE_ADDRESS; - for (int slot = 0; slot < hardDriveItemHandler.getSlots(); slot++) { - final Collection devices = hardDriveItemHandler.getBusElement().getDeviceGroup(slot); - for (final ItemDeviceInfo info : devices) { - if (Objects.equals(info.device, wrapper)) { - return OptionalLong.of(address); - } + for (final Map.Entry entry : itemHandlers.entrySet()) { + final DeviceType deviceType = entry.getKey(); + final DeviceItemStackHandler handler = entry.getValue(); + + // Ahhh, such special casing, much wow. Honestly I don't expect this + // special case to ever be needed for anything other than physical + // memory, so it's fine. Prove me wrong. + if (deviceType == DeviceTypes.MEMORY) { + continue; } - address += ITEM_DEVICE_STRIDE; - } - - for (int slot = 0; slot < cardItemHandler.getSlots(); slot++) { - final Collection devices = cardItemHandler.getBusElement().getDeviceGroup(slot); - for (final ItemDeviceInfo info : devices) { - if (Objects.equals(info.device, wrapper)) { - return OptionalLong.of(address); + for (int i = 0; i < handler.getSlots(); i++) { + final Collection devices = handler.getBusElement().getDeviceGroup(i); + for (final ItemDeviceInfo info : devices) { + if (Objects.equals(info.device, wrapper)) { + return OptionalLong.of(address); + } } } @@ -120,36 +123,30 @@ public abstract class AbstractVirtualMachineItemStackHandlers implements Virtual @Override public void exportDeviceDataToItemStacks() { - memoryItemHandler.exportDeviceDataToItemStacks(); - hardDriveItemHandler.exportDeviceDataToItemStacks(); - flashMemoryItemHandler.exportDeviceDataToItemStacks(); - cardItemHandler.exportDeviceDataToItemStacks(); + for (final DeviceItemStackHandler handler : itemHandlers.values()) { + handler.exportDeviceDataToItemStacks(); + } } public void exportToItemStack(final ItemStack stack) { - final CompoundNBT items = ItemStackUtils.getOrCreateTileEntityInventoryTag(stack); - items.put(MEMORY_TAG_NAME, memoryItemHandler.serializeNBT()); - items.put(HARD_DRIVE_TAG_NAME, hardDriveItemHandler.serializeNBT()); - items.put(FLASH_MEMORY_TAG_NAME, flashMemoryItemHandler.serializeNBT()); - items.put(CARD_TAG_NAME, cardItemHandler.serializeNBT()); + final CompoundNBT tag = ItemStackUtils.getOrCreateTileEntityInventoryTag(stack); + + itemHandlers.forEach((deviceType, handler) -> + tag.put(deviceType.getRegistryName().toString(), handler.serializeNBT())); } public CompoundNBT serialize() { final CompoundNBT tag = new CompoundNBT(); - tag.put(MEMORY_TAG_NAME, memoryItemHandler.serializeNBT()); - tag.put(HARD_DRIVE_TAG_NAME, hardDriveItemHandler.serializeNBT()); - tag.put(FLASH_MEMORY_TAG_NAME, flashMemoryItemHandler.serializeNBT()); - tag.put(CARD_TAG_NAME, cardItemHandler.serializeNBT()); + itemHandlers.forEach((deviceType, handler) -> + tag.put(deviceType.getRegistryName().toString(), handler.serializeNBT())); return tag; } public void deserialize(final CompoundNBT tag) { - memoryItemHandler.deserializeNBT(tag.getCompound(MEMORY_TAG_NAME)); - hardDriveItemHandler.deserializeNBT(tag.getCompound(HARD_DRIVE_TAG_NAME)); - flashMemoryItemHandler.deserializeNBT(tag.getCompound(FLASH_MEMORY_TAG_NAME)); - cardItemHandler.deserializeNBT(tag.getCompound(CARD_TAG_NAME)); + itemHandlers.forEach((deviceType, handler) -> + handler.deserializeNBT(tag.getCompound(deviceType.getRegistryName().toString()))); } /////////////////////////////////////////////////////////////////// @@ -176,12 +173,9 @@ public abstract class AbstractVirtualMachineItemStackHandlers implements Virtual private final class BusElement extends AbstractDeviceBusElement { @Override public Optional>> getNeighbors() { - return Optional.of(Arrays.asList( - LazyOptional.of(memoryItemHandler::getBusElement), - LazyOptional.of(hardDriveItemHandler::getBusElement), - LazyOptional.of(flashMemoryItemHandler::getBusElement), - LazyOptional.of(cardItemHandler::getBusElement) - )); + return Optional.of(itemHandlers.values().stream() + .map(h -> LazyOptional.of(() -> (DeviceBusElement) h.getBusElement())) + .collect(Collectors.toList())); } } }