diff --git a/src/main/java/li/cil/oc2/client/model/BusCableBakedModel.java b/src/main/java/li/cil/oc2/client/model/BusCableBakedModel.java index ab1a1bc2..099114cd 100644 --- a/src/main/java/li/cil/oc2/client/model/BusCableBakedModel.java +++ b/src/main/java/li/cil/oc2/client/model/BusCableBakedModel.java @@ -7,7 +7,6 @@ import li.cil.oc2.common.block.BusCableBlock; import li.cil.oc2.common.blockentity.BusCableBlockEntity; import li.cil.oc2.common.util.ItemStackUtils; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.BlockModelShaper; import net.minecraft.client.renderer.block.model.BakedQuad; @@ -25,7 +24,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.EnumProperty; import net.minecraftforge.client.model.IDynamicBakedModel; import net.minecraftforge.client.model.data.ModelData; -import net.minecraftforge.client.model.data.ModelDataManager; import net.minecraftforge.client.model.data.ModelProperty; import javax.annotation.Nonnull; @@ -35,8 +33,8 @@ import java.util.Collections; import java.util.List; public final class BusCableBakedModel implements IDynamicBakedModel { - private static final ModelProperty BUS_CABLE_SUPPORT_PROPERTY = new ModelProperty<>(); - private static final ModelProperty BUS_CABLE_FACADE_PROPERTY = new ModelProperty<>(); + public static final ModelProperty BUS_CABLE_SUPPORT_PROPERTY = new ModelProperty<>(); + public static final ModelProperty BUS_CABLE_FACADE_PROPERTY = new ModelProperty<>(); private final BakedModel proxy; private final BakedModel[] straightModelByAxis; private final BakedModel[] supportModelByFace; @@ -57,14 +55,14 @@ public final class BusCableBakedModel implements IDynamicBakedModel { if (extraData.has(BUS_CABLE_FACADE_PROPERTY)) { final BusCableFacade facade = extraData.get(BUS_CABLE_FACADE_PROPERTY); - if (facade != null && (layer == null)) { + if (facade != null) { return facade.model.getQuads(facade.blockState, side, rand, facade.data, RenderType.solid()); } else { return Collections.emptyList(); } } - if (state == null || !state.getValue(BusCableBlock.HAS_CABLE) || layer == null || !layer.equals(RenderType.solid())) { + if (state == null || !state.getValue(BusCableBlock.HAS_CABLE) || !layer.equals(RenderType.solid())) { return Collections.emptyList(); } @@ -165,7 +163,7 @@ public final class BusCableBakedModel implements IDynamicBakedModel { /////////////////////////////////////////////////////////////////// - private static boolean isNeighborInDirectionSolid(final BlockAndTintGetter level, final BlockPos pos, final Direction direction) { + public static boolean isNeighborInDirectionSolid(final BlockAndTintGetter level, final BlockPos pos, final Direction direction) { final BlockPos neighborPos = pos.relative(direction); return level.getBlockState(neighborPos).isFaceSturdy(level, neighborPos, direction.getOpposite()); } @@ -189,7 +187,7 @@ public final class BusCableBakedModel implements IDynamicBakedModel { /////////////////////////////////////////////////////////////////// - private record BusCableSupportSide(Direction value) { } + public record BusCableSupportSide(Direction value) { } - private record BusCableFacade(BlockState blockState, BakedModel model, ModelData data) { } + public record BusCableFacade(BlockState blockState, BakedModel model, ModelData data) { } } diff --git a/src/main/java/li/cil/oc2/client/model/BusCableModel.java b/src/main/java/li/cil/oc2/client/model/BusCableModel.java index 2126a042..d2f82a28 100644 --- a/src/main/java/li/cil/oc2/client/model/BusCableModel.java +++ b/src/main/java/li/cil/oc2/client/model/BusCableModel.java @@ -2,7 +2,6 @@ package li.cil.oc2.client.model; -import com.mojang.datafixers.util.Pair; import li.cil.oc2.api.API; import net.minecraft.client.renderer.block.model.ItemOverrides; import net.minecraft.client.renderer.texture.TextureAtlasSprite; @@ -11,9 +10,6 @@ import net.minecraft.resources.ResourceLocation; import net.minecraftforge.client.model.geometry.IGeometryBakingContext; import net.minecraftforge.client.model.geometry.IUnbakedGeometry; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Set; import java.util.function.Function; import static java.util.Objects.requireNonNull; @@ -46,6 +42,6 @@ public final class BusCableModel implements IUnbakedGeometry { requireNonNull(baker.bake(BUS_CABLE_SUPPORT_MODEL, BlockModelRotation.X0_Y270, spriteGetter)) // +x }; - return new BusCableBakedModel(proxy.bake(owner, baker, spriteGetter, modelTransform, overrides, modelLocation), straightModelByAxis, supportModelByFace); + return new BusCableBakedModel(bakedBaseModel, straightModelByAxis, supportModelByFace); } } diff --git a/src/main/java/li/cil/oc2/common/blockentity/BusCableBlockEntity.java b/src/main/java/li/cil/oc2/common/blockentity/BusCableBlockEntity.java index cea17a6f..03112f73 100644 --- a/src/main/java/li/cil/oc2/common/blockentity/BusCableBlockEntity.java +++ b/src/main/java/li/cil/oc2/common/blockentity/BusCableBlockEntity.java @@ -4,6 +4,7 @@ package li.cil.oc2.common.blockentity; import li.cil.oc2.api.bus.DeviceBus; import li.cil.oc2.api.bus.DeviceBusElement; +import li.cil.oc2.client.model.BusCableBakedModel; import li.cil.oc2.common.Config; import li.cil.oc2.common.Constants; import li.cil.oc2.common.block.BusCableBlock; @@ -18,6 +19,9 @@ import li.cil.oc2.common.util.ItemStackUtils; import li.cil.oc2.common.util.LevelUtils; import li.cil.oc2.common.util.NBTTagIds; import li.cil.oc2.common.util.ServerScheduler; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.BlockModelShaper; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -29,11 +33,13 @@ import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraftforge.client.model.data.ModelData; import net.minecraftforge.common.util.LazyOptional; import javax.annotation.Nullable; @@ -41,6 +47,7 @@ import java.util.HashSet; import java.util.Objects; import static java.util.Objects.requireNonNull; +import static li.cil.oc2.client.model.BusCableBakedModel.*; public final class BusCableBlockEntity extends ModBlockEntity { public enum FacadeType { @@ -49,6 +56,8 @@ public final class BusCableBlockEntity extends ModBlockEntity { VALID_BLOCK, } + private ModelData currentModelData = ModelData.EMPTY; + private static final String BUS_ELEMENT_TAG_NAME = "busElement"; private static final String INTERFACE_NAMES_TAG_NAME = "interfaceNames"; private static final String FACADE_TAG_NAME = "facade"; @@ -68,6 +77,8 @@ public final class BusCableBlockEntity extends ModBlockEntity { for (final Direction side : Direction.values()) { neighborTrackers[side.get3DDataValue()] = new NeighborTracker(side); } + + requestModelDataUpdate(); } /////////////////////////////////////////////////////////////////// @@ -145,6 +156,8 @@ public final class BusCableBlockEntity extends ModBlockEntity { final BusCableFacadeMessage message = new BusCableFacadeMessage(getBlockPos(), facade); Network.sendToClientsTrackingBlockEntity(message, this); } + + requestModelDataUpdate(); } public void removeFacade() { @@ -163,6 +176,8 @@ public final class BusCableBlockEntity extends ModBlockEntity { final BusCableFacadeMessage message = new BusCableFacadeMessage(getBlockPos(), facade); Network.sendToClientsTrackingBlockEntity(message, this); } + + requestModelDataUpdate(); } public void handleNeighborChanged(final BlockPos pos) { @@ -192,6 +207,56 @@ public final class BusCableBlockEntity extends ModBlockEntity { } } + @Override + public ModelData getModelData() + { + if (level == null) return ModelData.EMPTY; + BlockState state = getBlockState(); + BlockPos pos = getBlockPos(); + if (state.hasProperty(BusCableBlock.HAS_FACADE) && state.getValue(BusCableBlock.HAS_FACADE)) { + BlockState facadeState; + final ItemStack facadeItem = getFacade(); + + facadeState = ItemStackUtils.getBlockState(facadeItem); + if (facadeState == null) { + facadeState = Blocks.IRON_BLOCK.defaultBlockState(); + } + + final BlockModelShaper shapes = Minecraft.getInstance().getBlockRenderer().getBlockModelShaper(); + final BakedModel model = shapes.getBlockModel(facadeState); + ModelData data = model.getModelData(level, pos, facadeState, currentModelData); + + currentModelData = ModelData.builder() + .with(BUS_CABLE_FACADE_PROPERTY, new BusCableBakedModel.BusCableFacade(facadeState, model, data)) + .build(); + + return currentModelData; + } + + Direction supportSide = null; + for (final Direction direction : Constants.DIRECTIONS) { + if (isNeighborInDirectionSolid(level, pos, direction)) { + final EnumProperty property = BusCableBlock.FACING_TO_CONNECTION_MAP.get(direction); + if (state.hasProperty(property) && state.getValue(property) == BusCableBlock.ConnectionType.INTERFACE) { + return currentModelData; // Plug is already supporting us, bail. + } + + if (supportSide == null) { // Prefer vertical supports. + supportSide = direction; + } + } + } + + if (supportSide != null) { + currentModelData = ModelData.builder() + .with(BUS_CABLE_SUPPORT_PROPERTY, new BusCableBakedModel.BusCableSupportSide(supportSide)) + .build(); + return currentModelData; + } + + return currentModelData; + } + @Override public CompoundTag getUpdateTag() { final CompoundTag tag = super.getUpdateTag(); @@ -223,6 +288,8 @@ public final class BusCableBlockEntity extends ModBlockEntity { busElement.load(tag.getCompound(BUS_ELEMENT_TAG_NAME)); deserializeInterfaceNames(tag.getList(INTERFACE_NAMES_TAG_NAME, NBTTagIds.TAG_STRING)); facade = ItemStack.of(tag.getCompound(FACADE_TAG_NAME)); + + requestModelDataUpdate(); } /////////////////////////////////////////////////////////////////// @@ -244,6 +311,8 @@ public final class BusCableBlockEntity extends ModBlockEntity { } scheduleBusScanInAdjacentBusElements(); + + requestModelDataUpdate(); } @Override diff --git a/src/main/java/li/cil/oc2/common/blockentity/ComputerBlockEntity.java b/src/main/java/li/cil/oc2/common/blockentity/ComputerBlockEntity.java index 4a500e2a..356fd2ec 100644 --- a/src/main/java/li/cil/oc2/common/blockentity/ComputerBlockEntity.java +++ b/src/main/java/li/cil/oc2/common/blockentity/ComputerBlockEntity.java @@ -4,13 +4,11 @@ package li.cil.oc2.common.blockentity; import li.cil.oc2.api.bus.DeviceBusElement; import li.cil.oc2.api.bus.device.Device; -import li.cil.oc2.api.bus.device.DeviceType; import li.cil.oc2.api.bus.device.DeviceTypes; import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; import li.cil.oc2.api.capabilities.TerminalUserProvider; import li.cil.oc2.client.audio.LoopingSoundManager; import li.cil.oc2.common.Config; -import li.cil.oc2.common.Constants; import li.cil.oc2.common.block.ComputerBlock; import li.cil.oc2.common.bus.AbstractBlockDeviceBusElement; import li.cil.oc2.common.bus.BlockDeviceBusController; @@ -19,9 +17,7 @@ import li.cil.oc2.common.bus.device.util.Devices; import li.cil.oc2.common.capabilities.Capabilities; import li.cil.oc2.common.container.ComputerInventoryContainer; import li.cil.oc2.common.container.ComputerTerminalContainer; -import li.cil.oc2.common.container.DeviceTypeSlotItemHandler; import li.cil.oc2.common.energy.FixedEnergyStorage; -import li.cil.oc2.common.item.CPUItem; import li.cil.oc2.common.network.Network; import li.cil.oc2.common.network.message.ComputerBootErrorMessage; import li.cil.oc2.common.network.message.ComputerBusStateMessage; @@ -36,7 +32,6 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.state.BlockState; @@ -107,12 +102,6 @@ public final class ComputerBlockEntity extends ModBlockEntity implements Termina public void start() { if (level != null && !level.isClientSide()) { - if (deviceItems.getItemHandler(DeviceTypes.CPU).get().getStackInSlot(0).isEmpty()) - { - virtualMachine.error(Component.translatable(Constants.COMPUTER_ERROR_MISSING_CPU)); - return; - } - virtualMachine.state.board.getCpu().setFrequency(((CPUItem) deviceItems.getItemHandler(DeviceTypes.CPU).get().getStackInSlot(0).getItem()).getFrequency()); virtualMachine.start(); } } 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 a53c0ed8..9a02b0a7 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 @@ -4,24 +4,13 @@ package li.cil.oc2.common.bus.device; import li.cil.oc2.api.API; import li.cil.oc2.api.bus.device.DeviceType; -import li.cil.oc2.client.ClientSetup; import li.cil.oc2.common.bus.device.util.DeviceTypeImpl; import li.cil.oc2.common.tags.ItemTags; -import li.cil.oc2.common.util.RegistryUtils; -import net.minecraft.client.Minecraft; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.repository.Pack; import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.fml.loading.FMLEnvironment; import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.IForgeRegistry; -import net.minecraftforge.registries.RegistryBuilder; - -import java.util.function.Supplier; import static li.cil.oc2.common.util.TranslationUtils.text; @@ -30,10 +19,6 @@ public final class DeviceTypes { /////////////////////////////////////////////////////////////////// - public static final Supplier> DEVICE_TYPE_REGISTRY = DEVICE_TYPES.makeRegistry(RegistryBuilder::new); - - /////////////////////////////////////////////////////////////////// - public static void initialize() { DEVICE_TYPES.register(FMLJavaModLoadingContext.get().getModEventBus()); @@ -56,7 +41,5 @@ public final class DeviceTypes { new ResourceLocation(API.MOD_ID, "item/" + id + "_slot"), text("gui.{mod}.device_type." + id) )); - - System.out.println("gui/icon/" + id); } } diff --git a/src/main/java/li/cil/oc2/common/bus/device/provider/ProviderRegistry.java b/src/main/java/li/cil/oc2/common/bus/device/provider/ProviderRegistry.java index 5f5bc3b1..547227f9 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/provider/ProviderRegistry.java +++ b/src/main/java/li/cil/oc2/common/bus/device/provider/ProviderRegistry.java @@ -9,9 +9,6 @@ import li.cil.oc2.api.util.Registries; import li.cil.oc2.common.bus.device.provider.block.BlockEntityCapabilityDeviceProvider; import li.cil.oc2.common.bus.device.provider.item.*; import li.cil.oc2.common.bus.device.rpc.block.*; -import li.cil.oc2.common.util.RegistryUtils; -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.IForgeRegistry; @@ -44,6 +41,7 @@ public final class ProviderRegistry { ITEM_DEVICE_PROVIDERS.register("network_tunnel_card", NetworkTunnelCardItemDeviceProvider::new); ITEM_DEVICE_PROVIDERS.register("file_import_export_card", FileImportExportCardItemDeviceProvider::new); ITEM_DEVICE_PROVIDERS.register("sound_card", SoundCardItemDeviceProvider::new); + ITEM_DEVICE_PROVIDERS.register("cpu", CPUItemDeviceProvider::new); ITEM_DEVICE_PROVIDERS.register("inventory_operations_module", InventoryOperationsModuleDeviceProvider::new); ITEM_DEVICE_PROVIDERS.register("block_operations_module", BlockOperationsModuleDeviceProvider::new); diff --git a/src/main/java/li/cil/oc2/common/bus/device/provider/item/CPUItemDeviceProvider.java b/src/main/java/li/cil/oc2/common/bus/device/provider/item/CPUItemDeviceProvider.java new file mode 100644 index 00000000..21067a06 --- /dev/null +++ b/src/main/java/li/cil/oc2/common/bus/device/provider/item/CPUItemDeviceProvider.java @@ -0,0 +1,27 @@ +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.provider.util.AbstractItemDeviceProvider; +import li.cil.oc2.common.bus.device.rpc.item.CPUItemDevice; +import li.cil.oc2.common.item.CPUItem; + +import java.util.Optional; + +public class CPUItemDeviceProvider extends AbstractItemDeviceProvider { + public CPUItemDeviceProvider() { + super(CPUItem.class); + } + + /////////////////////////////////////////////////////////////////// + + @Override + protected Optional getItemDevice(final ItemDeviceQuery query) { + return Optional.of(new CPUItemDevice(query.getItemStack())); + } + + @Override + protected int getItemDeviceEnergyConsumption(final ItemDeviceQuery query) { + return 1; + } +} diff --git a/src/main/java/li/cil/oc2/common/bus/device/rpc/item/CPUItemDevice.java b/src/main/java/li/cil/oc2/common/bus/device/rpc/item/CPUItemDevice.java new file mode 100644 index 00000000..865acd26 --- /dev/null +++ b/src/main/java/li/cil/oc2/common/bus/device/rpc/item/CPUItemDevice.java @@ -0,0 +1,19 @@ +package li.cil.oc2.common.bus.device.rpc.item; + +import li.cil.oc2.api.bus.device.object.Callback; +import li.cil.oc2.common.item.CPUItem; +import net.minecraft.world.item.ItemStack; + +public class CPUItemDevice extends AbstractItemRPCDevice { + private final int frequency; + public CPUItemDevice(final ItemStack identity) { + super(identity, "cpu"); + frequency = ((CPUItem) identity.getItem()).getFrequency(); + } + + @Callback + public int getFrequency() + { + return frequency; + } +} diff --git a/src/main/java/li/cil/oc2/common/entity/Robot.java b/src/main/java/li/cil/oc2/common/entity/Robot.java index ada76fd4..584f24da 100644 --- a/src/main/java/li/cil/oc2/common/entity/Robot.java +++ b/src/main/java/li/cil/oc2/common/entity/Robot.java @@ -11,7 +11,6 @@ import li.cil.oc2.api.bus.device.object.Parameter; import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; import li.cil.oc2.api.capabilities.TerminalUserProvider; import li.cil.oc2.common.Config; -import li.cil.oc2.common.Constants; import li.cil.oc2.common.bus.AbstractDeviceBusElement; import li.cil.oc2.common.bus.CommonDeviceBusController; import li.cil.oc2.common.bus.device.util.Devices; @@ -22,7 +21,6 @@ import li.cil.oc2.common.container.RobotTerminalContainer; import li.cil.oc2.common.energy.FixedEnergyStorage; import li.cil.oc2.common.entity.robot.*; import li.cil.oc2.common.integration.Wrenches; -import li.cil.oc2.common.item.CPUItem; import li.cil.oc2.common.item.Items; import li.cil.oc2.common.network.Network; import li.cil.oc2.common.network.message.*; @@ -209,12 +207,6 @@ public final class Robot extends Entity implements li.cil.oc2.api.capabilities.R public void start() { if (!level().isClientSide()) { - if (deviceItems.getItemHandler(DeviceTypes.CPU).get().getStackInSlot(0).isEmpty()) - { - virtualMachine.error(Component.translatable(Constants.COMPUTER_ERROR_MISSING_CPU)); - return; - } - virtualMachine.state.board.getCpu().setFrequency(((CPUItem) deviceItems.getItemHandler(DeviceTypes.CPU).get().getStackInSlot(0).getItem()).getFrequency()); virtualMachine.start(); } } @@ -657,6 +649,9 @@ public final class Robot extends Entity implements li.cil.oc2.api.capabilities.R if (action != null) { action.initialize(Robot.this); } + else { + return; + } } RobotActions.performServer(Robot.this, action); } diff --git a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachine.java b/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachine.java index 9a66d250..3ec3cc17 100644 --- a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachine.java +++ b/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachine.java @@ -3,11 +3,13 @@ package li.cil.oc2.common.vm; import li.cil.ceres.api.Serialized; +import li.cil.oc2.api.bus.device.Device; import li.cil.oc2.api.bus.device.vm.FirmwareLoader; import li.cil.oc2.api.bus.device.vm.VMDeviceLoadResult; import li.cil.oc2.common.Constants; import li.cil.oc2.common.bus.CommonDeviceBusController; import li.cil.oc2.common.bus.RPCDeviceBusAdapter; +import li.cil.oc2.common.bus.device.rpc.item.CPUItemDevice; import li.cil.oc2.common.serialization.NBTSerialization; import li.cil.oc2.common.util.NBTTagIds; import li.cil.oc2.common.util.NBTUtils; @@ -24,6 +26,7 @@ import org.apache.logging.log4j.Logger; import javax.annotation.Nullable; import java.time.Duration; +import java.util.Optional; public abstract class AbstractVirtualMachine implements VirtualMachine { private static final Logger LOGGER = LogManager.getLogger(); @@ -296,6 +299,18 @@ public abstract class AbstractVirtualMachine implements VirtualMachine { return; } + if (busController.getDevices().stream().noneMatch(device -> device instanceof CPUItemDevice)) { + error(Component.translatable(Constants.COMPUTER_ERROR_MISSING_CPU)); + return; + } else { + Optional cpu = busController.getDevices().stream().filter(device -> device instanceof CPUItemDevice).findFirst(); + if(cpu.isEmpty()) { + error(Component.translatable(Constants.COMPUTER_ERROR_MISSING_CPU)); + return; + } + state.board.getCpu().setFrequency(((CPUItemDevice) cpu.get()).getFrequency()); + } + assert runner == null : "Runner active while still in load phase."; final VMDeviceLoadResult loadResult = state.vmAdapter.mountDevices();