Added block operations module for breaking and placing blocks.
This commit is contained in:
@@ -1,13 +1,18 @@
|
||||
package li.cil.oc2.common;
|
||||
|
||||
import li.cil.oc2.api.API;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.common.ToolType;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Mod.EventBusSubscriber(modid = API.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||
public final class Config {
|
||||
private static final CommonSettings COMMON_INSTANCE;
|
||||
@@ -20,6 +25,10 @@ public final class Config {
|
||||
public static int maxHardDriveSize = 8 * Constants.MEGABYTE;
|
||||
public static int maxFlashMemorySize = 4 * Constants.KILOBYTE;
|
||||
|
||||
public static int blockOperationsModuleToolLevel = Items.DIAMOND_PICKAXE.getHarvestLevel(new ItemStack(Items.DIAMOND_PICKAXE), ToolType.PICKAXE, null, null);
|
||||
|
||||
public static UUID fakePlayerUUID = UUID.fromString("e39dd9a7-514f-4a2d-aa5e-b6030621416d");
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
static {
|
||||
@@ -43,6 +52,8 @@ public final class Config {
|
||||
maxMemorySize = COMMON_INSTANCE.maxMemorySize.get();
|
||||
maxHardDriveSize = COMMON_INSTANCE.maxHardDriveSize.get();
|
||||
maxFlashMemorySize = COMMON_INSTANCE.maxFlashMemorySize.get();
|
||||
|
||||
fakePlayerUUID = UUID.fromString(COMMON_INSTANCE.fakePlayerUUID.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +65,10 @@ public final class Config {
|
||||
public ForgeConfigSpec.IntValue maxHardDriveSize;
|
||||
public ForgeConfigSpec.IntValue maxFlashMemorySize;
|
||||
|
||||
public ForgeConfigSpec.IntValue blockOperationsModuleToolLevel;
|
||||
|
||||
public ForgeConfigSpec.ConfigValue<String> fakePlayerUUID;
|
||||
|
||||
public CommonSettings(final ForgeConfigSpec.Builder builder) {
|
||||
builder.push("vm");
|
||||
|
||||
@@ -78,6 +93,24 @@ public final class Config {
|
||||
.defineInRange("maxFlashMemorySize", Config.maxFlashMemorySize, 0, 128 * Constants.MEGABYTE);
|
||||
|
||||
builder.pop();
|
||||
|
||||
builder.push("gameplay");
|
||||
|
||||
blockOperationsModuleToolLevel = builder
|
||||
.translation(Constants.CONFIG_BLOCK_OPERATIONS_MODULE_TOOL_LEVEL)
|
||||
.comment("Tool level the block operations module operates at.")
|
||||
.defineInRange("modules.block_operations.toolLevel", Config.blockOperationsModuleToolLevel, 0, Integer.MAX_VALUE);
|
||||
|
||||
builder.pop();
|
||||
|
||||
builder.push("admin");
|
||||
|
||||
fakePlayerUUID = builder
|
||||
.translation(Constants.CONFIG_FAKE_PLAYER_UUID)
|
||||
.comment("The UUID used for the ForgeFakePlayer used by robots.")
|
||||
.define("fakePlayerUUID", Config.fakePlayerUUID.toString());
|
||||
|
||||
builder.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,8 @@ public final class Constants {
|
||||
public static final String REDSTONE_INTERFACE_CARD_ITEM_NAME = "redstone_interface_card";
|
||||
public static final String NETWORK_INTERFACE_CARD_ITEM_NAME = "network_interface_card";
|
||||
|
||||
public static final String INVENTORY_AUTOMATION_MODULE_ITEM_NAME = "inventory_automation_module";
|
||||
public static final String INVENTORY_OPERATIONS_MODULE_ITEM_NAME = "inventory_operations_module";
|
||||
public static final String BLOCK_OPERATIONS_MODULE_ITEM_NAME = "block_operations_module";
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -51,10 +52,12 @@ public final class Constants {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static final String CONFIG_MAX_ALLOCATED_MEMORY = "config.oc2.maxAllocatedMemory";
|
||||
public static final String CONFIG_MAX_MEMORY_SIZE = "config.oc2.maxMemorySize";
|
||||
public static final String CONFIG_MAX_HARD_DRIVE_SIZE = "config.oc2.maxHardDriveSize";
|
||||
public static final String CONFIG_MAX_FLASH_MEMORY_SIZE = "config.oc2.maxFlashMemorySize";
|
||||
public static final String CONFIG_MAX_ALLOCATED_MEMORY = "config.oc2.vm.maxAllocatedMemory";
|
||||
public static final String CONFIG_MAX_MEMORY_SIZE = "config.oc2.vm.maxMemorySize";
|
||||
public static final String CONFIG_MAX_HARD_DRIVE_SIZE = "config.oc2.vm.maxHardDriveSize";
|
||||
public static final String CONFIG_MAX_FLASH_MEMORY_SIZE = "config.oc2.vm.maxFlashMemorySize";
|
||||
public static final String CONFIG_BLOCK_OPERATIONS_MODULE_TOOL_LEVEL = "config.oc2.modules.block_operations.toolLevel";
|
||||
public static final String CONFIG_FAKE_PLAYER_UUID = "config.oc2.admin.fakePlayerUUID";
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
package li.cil.oc2.common.bus.device.item;
|
||||
|
||||
import li.cil.oc2.api.bus.device.ItemDevice;
|
||||
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;
|
||||
import li.cil.oc2.api.bus.device.rpc.RPCDevice;
|
||||
import li.cil.oc2.api.bus.device.rpc.RPCMethod;
|
||||
import li.cil.oc2.api.capabilities.Robot;
|
||||
import li.cil.oc2.common.Config;
|
||||
import li.cil.oc2.common.bus.device.util.IdentityProxy;
|
||||
import li.cil.oc2.common.util.FakePlayerUtils;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.world.GameType;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.event.ForgeEventFactory;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public final class BlockOperationsModuleDevice extends IdentityProxy<ItemStack> implements RPCDevice, ItemDevice {
|
||||
public enum PlacementDirection {
|
||||
FRONT,
|
||||
UP,
|
||||
DOWN,
|
||||
}
|
||||
|
||||
private final Entity entity;
|
||||
private final Robot robot;
|
||||
private final ObjectDevice device;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public BlockOperationsModuleDevice(final ItemStack identity, final Entity entity, final Robot robot) {
|
||||
super(identity);
|
||||
this.entity = entity;
|
||||
this.robot = robot;
|
||||
this.device = new ObjectDevice(this, "block_operations");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public List<String> getTypeNames() {
|
||||
return device.getTypeNames();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RPCMethod> getMethods() {
|
||||
return device.getMethods();
|
||||
}
|
||||
|
||||
@Callback
|
||||
public boolean excavate(@Parameter("direction") @Nullable final PlacementDirection direction) {
|
||||
final World world = entity.getEntityWorld();
|
||||
if (!(world instanceof ServerWorld)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int selectedSlot = robot.getSelectedSlot(); // Get once to avoid change due to threading.
|
||||
final ItemStackHandler inventory = robot.getInventory();
|
||||
|
||||
final List<ItemEntity> oldItems = getItemsInRange();
|
||||
|
||||
if (!tryHarvestBlock(world, entity.getPosition().offset(getAdjustedDirection(direction)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final List<ItemEntity> droppedItems = getItemsInRange();
|
||||
droppedItems.removeAll(oldItems);
|
||||
|
||||
for (final ItemEntity itemEntity : droppedItems) {
|
||||
ItemStack stack = itemEntity.getItem();
|
||||
stack = insertStartingAt(inventory, stack, selectedSlot, false);
|
||||
itemEntity.setItem(stack);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Callback
|
||||
public boolean place(@Parameter("direction") @Nullable final PlacementDirection direction) {
|
||||
final World world = entity.getEntityWorld();
|
||||
if (!(world instanceof ServerWorld)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int selectedSlot = robot.getSelectedSlot(); // Get once to avoid change due to threading.
|
||||
final ItemStackHandler inventory = robot.getInventory();
|
||||
|
||||
final ItemStack extracted = inventory.extractItem(selectedSlot, 1, true);
|
||||
if (extracted.isEmpty() || !(extracted.getItem() instanceof BlockItem)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final BlockPos blockPos = entity.getPosition().offset(getAdjustedDirection(direction));
|
||||
final Direction side = getAdjustedDirection(direction).getOpposite();
|
||||
final BlockRayTraceResult hit = new BlockRayTraceResult(
|
||||
Vector3d.copyCentered(blockPos).add(Vector3d.copy(side.getDirectionVec()).scale(0.5)),
|
||||
side,
|
||||
blockPos,
|
||||
false);
|
||||
|
||||
final ItemStack itemStack = extracted.copy();
|
||||
final BlockItem blockItem = (BlockItem) itemStack.getItem();
|
||||
final ServerPlayerEntity player = FakePlayerUtils.getFakePlayer((ServerWorld) world, entity);
|
||||
final BlockItemUseContext context = new BlockItemUseContext(player, Hand.MAIN_HAND, itemStack, hit);
|
||||
|
||||
final ActionResultType result = blockItem.tryPlace(context);
|
||||
if (!result.isSuccessOrConsume()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (itemStack.isEmpty()) {
|
||||
inventory.extractItem(selectedSlot, 1, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private Direction getAdjustedDirection(@Nullable final PlacementDirection placementDirection) {
|
||||
if (placementDirection == PlacementDirection.UP) {
|
||||
return Direction.UP;
|
||||
} else if (placementDirection == PlacementDirection.DOWN) {
|
||||
return Direction.DOWN;
|
||||
} else {
|
||||
Direction direction = Direction.SOUTH;
|
||||
final int horizontalIndex = entity.getHorizontalFacing().getHorizontalIndex();
|
||||
for (int i = 0; i < horizontalIndex; i++) {
|
||||
direction = direction.rotateY();
|
||||
}
|
||||
return direction;
|
||||
}
|
||||
}
|
||||
|
||||
private List<ItemEntity> getItemsInRange() {
|
||||
return entity.getEntityWorld().getEntitiesWithinAABB(ItemEntity.class, entity.getBoundingBox().grow(2));
|
||||
}
|
||||
|
||||
private boolean tryHarvestBlock(final World world, final BlockPos blockPos) {
|
||||
// This method is based on PlayerInteractionManager::tryHarvestBlock. Simplified for our needs.
|
||||
final BlockState blockState = world.getBlockState(blockPos);
|
||||
if (blockState.isAir(world, blockPos)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ServerPlayerEntity player = FakePlayerUtils.getFakePlayer((ServerWorld) world, entity);
|
||||
final int experience = net.minecraftforge.common.ForgeHooks.onBlockBreakEvent(world, GameType.NOT_SET, player, blockPos);
|
||||
if (experience == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final TileEntity tileEntity = world.getTileEntity(blockPos);
|
||||
final Block block = blockState.getBlock();
|
||||
final boolean isCommandBlock = block instanceof CommandBlockBlock || block instanceof StructureBlock || block instanceof JigsawBlock;
|
||||
if (isCommandBlock && !player.canUseCommandBlock()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player.blockActionRestricted(world, blockPos, GameType.NOT_SET)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final boolean canHarvest = Config.blockOperationsModuleToolLevel >= blockState.getHarvestLevel();
|
||||
if (!canHarvest) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ForgeEventFactory.doPlayerHarvestCheck(player, blockState, canHarvest)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!blockState.removedByPlayer(world, blockPos, player, true, world.getFluidState(blockPos))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
block.onPlayerDestroy(world, blockPos, blockState);
|
||||
block.harvestBlock(world, player, blockPos, blockState, tileEntity, ItemStack.EMPTY);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private ItemStack insertStartingAt(final IItemHandler handler, ItemStack stack, final int startSlot, final boolean simulate) {
|
||||
for (int i = 0; i < handler.getSlots(); i++) {
|
||||
final int slot = (startSlot + i) % handler.getSlots();
|
||||
stack = handler.insertItem(slot, stack, simulate);
|
||||
if (stack.isEmpty()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
@@ -29,18 +29,18 @@ import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public final class InventoryAutomationRobotModuleDevice extends IdentityProxy<ItemStack> implements RPCDevice, ItemDevice {
|
||||
public final class InventoryOperationsModuleDevice extends IdentityProxy<ItemStack> implements RPCDevice, ItemDevice {
|
||||
private final Entity entity;
|
||||
private final Robot robot;
|
||||
private final ObjectDevice device;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public InventoryAutomationRobotModuleDevice(final ItemStack identity, final Entity entity, final Robot robot) {
|
||||
public InventoryOperationsModuleDevice(final ItemStack identity, final Entity entity, final Robot robot) {
|
||||
super(identity);
|
||||
this.entity = entity;
|
||||
this.robot = robot;
|
||||
this.device = new ObjectDevice(this, "inventory_automation");
|
||||
this.device = new ObjectDevice(this, "inventory_operations");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -3,6 +3,7 @@ package li.cil.oc2.common.bus.device.provider;
|
||||
import li.cil.oc2.api.API;
|
||||
import li.cil.oc2.api.bus.device.provider.BlockDeviceProvider;
|
||||
import li.cil.oc2.api.bus.device.provider.ItemDeviceProvider;
|
||||
import li.cil.oc2.common.Constants;
|
||||
import li.cil.oc2.common.bus.device.provider.block.*;
|
||||
import li.cil.oc2.common.bus.device.provider.item.*;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
@@ -31,13 +32,14 @@ public final class Providers {
|
||||
BLOCK_DEVICE_PROVIDERS.register("fluid_handler", FluidHandlerBlockDeviceProvider::new);
|
||||
BLOCK_DEVICE_PROVIDERS.register("item_handler", ItemHandlerBlockDeviceProvider::new);
|
||||
|
||||
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);
|
||||
ITEM_DEVICE_PROVIDERS.register("item_network_interface_card", NetworkInterfaceCardItemDeviceProvider::new);
|
||||
ITEM_DEVICE_PROVIDERS.register(Constants.MEMORY_ITEM_NAME, MemoryItemDeviceProvider::new);
|
||||
ITEM_DEVICE_PROVIDERS.register(Constants.HARD_DRIVE_ITEM_NAME, HardDriveItemDeviceProvider::new);
|
||||
ITEM_DEVICE_PROVIDERS.register(Constants.FLASH_MEMORY_ITEM_NAME, FlashMemoryItemDeviceProvider::new);
|
||||
ITEM_DEVICE_PROVIDERS.register(Constants.REDSTONE_INTERFACE_CARD_ITEM_NAME, RedstoneInterfaceCardItemDeviceProvider::new);
|
||||
ITEM_DEVICE_PROVIDERS.register(Constants.NETWORK_INTERFACE_CARD_ITEM_NAME, NetworkInterfaceCardItemDeviceProvider::new);
|
||||
|
||||
ITEM_DEVICE_PROVIDERS.register("inventory_automation_module", InventoryAutomationRobotModuleDeviceProvider::new);
|
||||
ITEM_DEVICE_PROVIDERS.register(Constants.INVENTORY_OPERATIONS_MODULE_ITEM_NAME, InventoryOperationsModuleDeviceProvider::new);
|
||||
ITEM_DEVICE_PROVIDERS.register(Constants.BLOCK_OPERATIONS_MODULE_ITEM_NAME, BlockOperationsModuleDeviceProvider::new);
|
||||
|
||||
BLOCK_DEVICE_PROVIDERS.register(FMLJavaModLoadingContext.get().getModEventBus());
|
||||
ITEM_DEVICE_PROVIDERS.register(FMLJavaModLoadingContext.get().getModEventBus());
|
||||
|
||||
@@ -4,16 +4,16 @@ import li.cil.oc2.api.bus.device.DeviceType;
|
||||
import li.cil.oc2.api.bus.device.DeviceTypes;
|
||||
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.InventoryAutomationRobotModuleDevice;
|
||||
import li.cil.oc2.common.bus.device.item.BlockOperationsModuleDevice;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractItemDeviceProvider;
|
||||
import li.cil.oc2.common.capabilities.Capabilities;
|
||||
import li.cil.oc2.common.item.Items;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public final class InventoryAutomationRobotModuleDeviceProvider extends AbstractItemDeviceProvider {
|
||||
public InventoryAutomationRobotModuleDeviceProvider() {
|
||||
super(Items.INVENTORY_AUTOMATION_MODULE);
|
||||
public final class BlockOperationsModuleDeviceProvider extends AbstractItemDeviceProvider {
|
||||
public BlockOperationsModuleDeviceProvider() {
|
||||
super(Items.BLOCK_OPERATIONS_MODULE);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
@@ -27,6 +27,6 @@ public final class InventoryAutomationRobotModuleDeviceProvider extends Abstract
|
||||
protected Optional<ItemDevice> getItemDevice(final ItemDeviceQuery query) {
|
||||
return query.getContainerEntity().flatMap(entity ->
|
||||
entity.getCapability(Capabilities.ROBOT).map(robot ->
|
||||
new InventoryAutomationRobotModuleDevice(query.getItemStack(), entity, robot)));
|
||||
new BlockOperationsModuleDevice(query.getItemStack(), entity, robot)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package li.cil.oc2.common.bus.device.provider.item;
|
||||
|
||||
import li.cil.oc2.api.bus.device.DeviceType;
|
||||
import li.cil.oc2.api.bus.device.DeviceTypes;
|
||||
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.InventoryOperationsModuleDevice;
|
||||
import li.cil.oc2.common.bus.device.provider.util.AbstractItemDeviceProvider;
|
||||
import li.cil.oc2.common.capabilities.Capabilities;
|
||||
import li.cil.oc2.common.item.Items;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public final class InventoryOperationsModuleDeviceProvider extends AbstractItemDeviceProvider {
|
||||
public InventoryOperationsModuleDeviceProvider() {
|
||||
super(Items.INVENTORY_OPERATIONS_MODULE);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected Optional<DeviceType> getItemDeviceType(final ItemDeviceQuery query) {
|
||||
return Optional.of(DeviceTypes.ROBOT_MODULE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<ItemDevice> getItemDevice(final ItemDeviceQuery query) {
|
||||
return query.getContainerEntity().flatMap(entity ->
|
||||
entity.getCapability(Capabilities.ROBOT).map(robot ->
|
||||
new InventoryOperationsModuleDevice(query.getItemStack(), entity, robot)));
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,8 @@ public final class Items {
|
||||
public static final RegistryObject<Item> REDSTONE_INTERFACE_CARD_ITEM = register(Constants.REDSTONE_INTERFACE_CARD_ITEM_NAME);
|
||||
public static final RegistryObject<Item> NETWORK_INTERFACE_CARD_ITEM = register(Constants.NETWORK_INTERFACE_CARD_ITEM_NAME);
|
||||
|
||||
public static final RegistryObject<Item> INVENTORY_AUTOMATION_MODULE = register(Constants.INVENTORY_AUTOMATION_MODULE_ITEM_NAME);
|
||||
public static final RegistryObject<Item> INVENTORY_OPERATIONS_MODULE = register(Constants.INVENTORY_OPERATIONS_MODULE_ITEM_NAME);
|
||||
public static final RegistryObject<Item> BLOCK_OPERATIONS_MODULE = register(Constants.BLOCK_OPERATIONS_MODULE_ITEM_NAME);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
57
src/main/java/li/cil/oc2/common/util/FakePlayerUtils.java
Normal file
57
src/main/java/li/cil/oc2/common/util/FakePlayerUtils.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package li.cil.oc2.common.util;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.netty.util.concurrent.Future;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
import li.cil.oc2.api.API;
|
||||
import li.cil.oc2.common.Config;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.network.IPacket;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.PacketDirection;
|
||||
import net.minecraft.network.play.ServerPlayNetHandler;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.common.util.FakePlayerFactory;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class FakePlayerUtils {
|
||||
private static final String FAKE_PLAYER_NAME = "[" + API.MOD_ID + "]";
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static ServerPlayerEntity getFakePlayer(final ServerWorld world, final Entity entity) {
|
||||
final ServerPlayerEntity player = getFakePlayer(world);
|
||||
player.copyLocationAndAnglesFrom(entity);
|
||||
player.prevRotationPitch = player.rotationPitch;
|
||||
player.prevRotationYaw = player.rotationYaw;
|
||||
player.rotationYawHead = player.rotationYaw;
|
||||
player.prevRotationYawHead = player.rotationYawHead;
|
||||
return player;
|
||||
}
|
||||
|
||||
public static ServerPlayerEntity getFakePlayer(final ServerWorld world) {
|
||||
final FakePlayer player = FakePlayerFactory.get(world, new GameProfile(Config.fakePlayerUUID, FAKE_PLAYER_NAME));
|
||||
|
||||
// We need to give our fake player a fake network handler because some events we want
|
||||
// to use the fake player with will unconditionally access this field.
|
||||
if (player.connection == null) {
|
||||
player.connection = new FakeServerPlayNetHandler(player);
|
||||
}
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private static class FakeServerPlayNetHandler extends ServerPlayNetHandler {
|
||||
public FakeServerPlayNetHandler(final FakePlayer fakePlayer) {
|
||||
super(fakePlayer.server, new NetworkManager(PacketDirection.CLIENTBOUND), fakePlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(final IPacket<?> packetIn, @Nullable final GenericFutureListener<? extends Future<? super Void>> futureListeners) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package li.cil.oc2.common.util;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
@@ -11,6 +13,7 @@ import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.IWorld;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class WorldUtils {
|
||||
|
||||
@@ -45,7 +45,8 @@ public final class ModItemModelProvider extends ItemModelProvider {
|
||||
simple(Items.REDSTONE_INTERFACE_CARD_ITEM, "items/redstone_interface_card");
|
||||
simple(Items.NETWORK_INTERFACE_CARD_ITEM, "items/network_interface_card");
|
||||
|
||||
simple(Items.INVENTORY_AUTOMATION_MODULE, "items/inventory_automation_module");
|
||||
simple(Items.INVENTORY_OPERATIONS_MODULE, "items/inventory_operations_module");
|
||||
simple(Items.BLOCK_OPERATIONS_MODULE, "items/block_operations_module");
|
||||
|
||||
withExistingParent(Constants.ROBOT_ENTITY_NAME, "template_shulker_box");
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ public final class ModItemTagsProvider extends ItemTagsProvider {
|
||||
Items.NETWORK_INTERFACE_CARD_ITEM.get()
|
||||
);
|
||||
getOrCreateBuilder(DEVICES_ROBOT_MODULE).add(
|
||||
Items.INVENTORY_AUTOMATION_MODULE.get()
|
||||
Items.INVENTORY_OPERATIONS_MODULE.get(),
|
||||
Items.BLOCK_OPERATIONS_MODULE.get()
|
||||
);
|
||||
getOrCreateBuilder(WRENCHES).add(Items.WRENCH_ITEM.get());
|
||||
}
|
||||
|
||||
@@ -21,15 +21,20 @@
|
||||
"item.oc2.network_interface_card": "Network Interface Card",
|
||||
"item.oc2.robot": "Robot",
|
||||
"item.oc2.robot.desc": "Use a Scrench or compatible wrench to add and remove components.",
|
||||
"item.oc2.inventory_automation_module": "Inventory Automation Module",
|
||||
"item.oc2.inventory_operations_module": "Inventory Operations Module",
|
||||
"item.oc2.inventory_operations_module.desc": "Enables robots to move items in their inventory, including to and from adjacent inventories.",
|
||||
"item.oc2.block_operations_module": "Block Operations Module",
|
||||
"item.oc2.block_operations_module.desc": "Enables robots to break and place blocks.",
|
||||
|
||||
"entity.oc2.robot": "Robot",
|
||||
|
||||
"config.oc2.maxAllocatedMemory": "Maximum allocated memory",
|
||||
"config.oc2.maxMemorySize:": "Maximum memory device size",
|
||||
"config.oc2.maxHardDriveSize": "Maximum hard drive device size",
|
||||
"config.oc2.maxFlashMemorySize:": "Maximum flash memory device size",
|
||||
"config.oc2.vm.maxAllocatedMemory": "Maximum allocated memory",
|
||||
"config.oc2.vm.maxMemorySize:": "Maximum memory device size",
|
||||
"config.oc2.vm.maxHardDriveSize": "Maximum hard drive device size",
|
||||
"config.oc2.vm.maxFlashMemorySize:": "Maximum flash memory device size",
|
||||
"config.oc2.computerEnergyPerTick": "Energy/tick used by computers",
|
||||
"config.oc2.modules.block_operations.toolLevel": "Block operations module tool level",
|
||||
"config.oc2.admin.fakePlayerUUID": "Fake Player UUID",
|
||||
|
||||
"gui.oc2.computer.boot_error.unknown": "Unknown Error",
|
||||
"gui.oc2.computer.boot_error.no_memory": "Insufficient Memory",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/handheld",
|
||||
"textures": {
|
||||
"layer0": "oc2:items/inventory_automation_module"
|
||||
"layer0": "oc2:items/block_operations_module"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/handheld",
|
||||
"textures": {
|
||||
"layer0": "oc2:items/inventory_operations_module"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"oc2:inventory_automation_module"
|
||||
"oc2:inventory_operations_module",
|
||||
"oc2:block_operations_module"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user