1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-25 22:53:22 +00:00

Some basic integration with MCMP

This allows wireless modems (advanced and normal) to be used in
multiparts. There's a very limited set of uses for this (mostly allows
using Chisel and Bits with them), but it's very simple to do.

I'd like to look into MCMP support for wired modems/cables in the
future, but this will be somewhat harder due to their pre-existing
multiblock structure.

Similarly, might be fun to look into CBMP compatibility.
This commit is contained in:
SquidDev 2019-03-14 21:19:55 +00:00
parent dd05478483
commit 765ad0bd3f
8 changed files with 313 additions and 30 deletions

View File

@ -57,6 +57,7 @@
}
ivy { artifactPattern "https://asie.pl/files/mods/Charset/LibOnly/[module]-[revision](-[classifier]).[ext]" }
maven { url "http://maven.amadornes.com/" }
}
configurations {
@ -68,6 +69,7 @@
dependencies {
deobfProvided "mezz.jei:jei_1.12.2:4.8.5.159:api"
deobfProvided "pl.asie:Charset-Lib:0.5.4.6"
deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
runtime "mezz.jei:jei_1.12.2:4.8.5.159"

View File

@ -24,10 +24,10 @@ public final class IntegrationCharset
private static final ResourceLocation CAPABILITY_KEY = new ResourceLocation( ComputerCraft.MOD_ID, "charset" );
@CapabilityInject( IBundledEmitter.class )
public static final Capability<IBundledEmitter> CAPABILITY_EMITTER = null;
static Capability<IBundledEmitter> CAPABILITY_EMITTER = null;
@CapabilityInject( IBundledReceiver.class )
public static final Capability<IBundledReceiver> CAPABILITY_RECEIVER = null;
static Capability<IBundledReceiver> CAPABILITY_RECEIVER = null;
private IntegrationCharset()
{
@ -37,12 +37,12 @@ public static void register()
{
if( CAPABILITY_EMITTER == null || CAPABILITY_RECEIVER == null ) return;
MinecraftForge.EVENT_BUS.register( new IntegrationCharset() );
MinecraftForge.EVENT_BUS.register( IntegrationCharset.class );
ComputerCraftAPI.registerBundledRedstoneProvider( new BundledRedstoneProvider() );
}
@SubscribeEvent
public void attachGenericCapabilities( AttachCapabilitiesEvent<TileEntity> event )
public static void attachGenericCapabilities( AttachCapabilitiesEvent<TileEntity> event )
{
TileEntity tile = event.getObject();
if( tile instanceof TileGeneric )

View File

@ -0,0 +1,51 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.mcmp;
import mcmultipart.MCMultiPart;
import mcmultipart.api.item.ItemBlockMultipart;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Loader;
import javax.annotation.Nonnull;
public final class MCMPHooks
{
private MCMPHooks()
{
}
public static EnumActionResult onItemUse( ItemBlock itemBlock, EntityPlayer player, World world, @Nonnull BlockPos pos, @Nonnull EnumHand hand, @Nonnull EnumFacing facing, float hitX, float hitY, float hitZ )
{
if( !Loader.isModLoaded( MCMultiPart.MODID ) ) return EnumActionResult.PASS;
return ItemBlockMultipart.place(
player, world, pos, hand, facing, hitX, hitY, hitZ, itemBlock,
itemBlock.getBlock()::getStateForPlacement,
MCMPIntegration.multipartMap.get( itemBlock.getBlock() ),
(
ItemStack stack, EntityPlayer thisPlayer, World thisWorld, BlockPos thisPos, EnumFacing thisFacing,
float thisX, float thisY, float thisZ, IBlockState thisState
) ->
thisPlayer.canPlayerEdit( thisPos, thisFacing, stack ) &&
thisWorld.getBlockState( thisPos ).getBlock().isReplaceable( thisWorld, thisPos ) &&
itemBlock.getBlock().canPlaceBlockAt( thisWorld, thisPos ) &&
itemBlock.getBlock().canPlaceBlockOnSide( thisWorld, thisPos, thisFacing ) &&
itemBlock.placeBlockAt( stack, thisPlayer, thisWorld, thisPos, thisFacing, thisX, thisY, thisZ, thisState ),
ItemBlockMultipart::placePartAt
);
}
}

View File

@ -0,0 +1,119 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.mcmp;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.peripheral.common.IPeripheralTile;
import dan200.computercraft.shared.peripheral.modem.wireless.TileAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.TileWirelessModem;
import mcmultipart.api.addon.IMCMPAddon;
import mcmultipart.api.addon.MCMPAddon;
import mcmultipart.api.container.IMultipartContainer;
import mcmultipart.api.multipart.IMultipart;
import mcmultipart.api.multipart.IMultipartRegistry;
import mcmultipart.api.multipart.IMultipartTile;
import mcmultipart.api.ref.MCMPCapabilities;
import mcmultipart.api.slot.EnumFaceSlot;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
@MCMPAddon
public class MCMPIntegration implements IMCMPAddon
{
private static final ResourceLocation CAPABILITY_KEY = new ResourceLocation( ComputerCraft.MOD_ID, "mcmultipart" );
static final Map<Block, IMultipart> multipartMap = new HashMap<>();
private static void register( IMultipartRegistry registry, Block block, IMultipart multipart )
{
registry.registerPartWrapper( block, multipart );
multipartMap.put( block, multipart );
}
@Override
public void registerParts( IMultipartRegistry registry )
{
// Setup all parts
register( registry, ComputerCraft.Blocks.peripheral, new PartNormalModem() );
register( registry, ComputerCraft.Blocks.advancedModem, new PartAdvancedModem() );
// Subscribe to capability events
MinecraftForge.EVENT_BUS.register( MCMPIntegration.class );
// Register a peripheral provider
ComputerCraftAPI.registerPeripheralProvider( ( world, pos, side ) ->
{
TileEntity tile = world.getTileEntity( pos );
if( tile == null || !tile.hasCapability( MCMPCapabilities.MULTIPART_CONTAINER, null ) ) return null;
IMultipartContainer container = tile.getCapability( MCMPCapabilities.MULTIPART_CONTAINER, null );
if( container == null ) return null;
IMultipartTile multipart = container.getPartTile( EnumFaceSlot.fromFace( side ) ).orElse( null );
if( multipart == null ) return null;
if( multipart instanceof IPeripheral ) return (IPeripheral) multipart;
if( multipart instanceof IPeripheralTile ) return ((IPeripheralTile) multipart).getPeripheral( side );
TileEntity underlying = multipart.getTileEntity();
if( underlying instanceof IPeripheral ) return (IPeripheral) underlying;
if( underlying instanceof IPeripheralTile ) return ((IPeripheralTile) underlying).getPeripheral( side );
return null;
} );
}
@SubscribeEvent
public static void attach( AttachCapabilitiesEvent<TileEntity> event )
{
TileEntity tile = event.getObject();
if( tile instanceof TileAdvancedModem || tile instanceof TileWirelessModem )
{
event.addCapability( CAPABILITY_KEY, new BasicMultipart( tile ) );
}
}
private static final class BasicMultipart implements ICapabilityProvider
{
private final TileEntity tile;
private IMultipartTile wrapped;
private BasicMultipart( TileEntity tile ) {this.tile = tile;}
@Override
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
{
return capability == MCMPCapabilities.MULTIPART_TILE;
}
@Nullable
@Override
public <T> T getCapability( @Nonnull Capability<T> capability, @Nullable EnumFacing facing )
{
if( capability == MCMPCapabilities.MULTIPART_TILE )
{
IMultipartTile wrapped = this.wrapped;
if( wrapped == null ) wrapped = this.wrapped = IMultipartTile.wrap( tile );
return MCMPCapabilities.MULTIPART_TILE.cast( wrapped );
}
return null;
}
}
}

View File

@ -0,0 +1,41 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.mcmp;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.modem.wireless.BlockAdvancedModem;
import mcmultipart.api.multipart.IMultipart;
import mcmultipart.api.slot.EnumFaceSlot;
import mcmultipart.api.slot.IPartSlot;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public class PartAdvancedModem implements IMultipart
{
@Override
public IPartSlot getSlotForPlacement( World world, BlockPos pos, IBlockState state, EnumFacing facing, float hitX, float hitY, float hitZ, EntityLivingBase placer )
{
return EnumFaceSlot.fromFace( state.getValue( BlockAdvancedModem.Properties.FACING ) );
}
@Override
public IPartSlot getSlotFromWorld( IBlockAccess world, BlockPos pos, IBlockState state )
{
return EnumFaceSlot.fromFace( state.getValue( BlockAdvancedModem.Properties.FACING ) );
}
@Override
public Block getBlock()
{
return ComputerCraft.Blocks.advancedModem;
}
}

View File

@ -0,0 +1,59 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.mcmp;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
import dan200.computercraft.shared.peripheral.common.BlockPeripheralVariant;
import mcmultipart.api.multipart.IMultipart;
import mcmultipart.api.slot.EnumFaceSlot;
import mcmultipart.api.slot.IPartSlot;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public class PartNormalModem implements IMultipart
{
@Override
public IPartSlot getSlotForPlacement( World world, BlockPos pos, IBlockState state, EnumFacing facing, float hitX, float hitY, float hitZ, EntityLivingBase placer )
{
return EnumFaceSlot.fromFace( getFacing( state ) );
}
@Override
public IPartSlot getSlotFromWorld( IBlockAccess world, BlockPos pos, IBlockState state )
{
return EnumFaceSlot.fromFace( getFacing( state ) );
}
private EnumFacing getFacing( IBlockState state )
{
BlockPeripheralVariant type = state.getValue( BlockPeripheral.Properties.VARIANT );
if( type == BlockPeripheralVariant.WirelessModemUpOn || type == BlockPeripheralVariant.WirelessModemUpOff )
{
return EnumFacing.UP;
}
else if( type == BlockPeripheralVariant.WirelessModemDownOn || type == BlockPeripheralVariant.WirelessModemDownOff )
{
return EnumFacing.UP;
}
else
{
return state.getValue( BlockPeripheral.Properties.FACING );
}
}
@Override
public Block getBlock()
{
return ComputerCraft.Blocks.peripheral;
}
}

View File

@ -7,11 +7,18 @@
package dan200.computercraft.shared.peripheral.common;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.integration.mcmp.MCMPHooks;
import dan200.computercraft.shared.peripheral.PeripheralType;
import net.minecraft.block.Block;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
@ -31,41 +38,27 @@ public ItemStack create( PeripheralType type, String label, int quantity )
switch( type )
{
case DiskDrive:
{
stack = new ItemStack( this, quantity, 0 );
break;
}
case WirelessModem:
{
stack = new ItemStack( this, quantity, 1 );
break;
}
case Monitor:
{
stack = new ItemStack( this, quantity, 2 );
break;
}
case Printer:
{
stack = new ItemStack( this, quantity, 3 );
break;
}
case AdvancedMonitor:
{
stack = new ItemStack( this, quantity, 4 );
break;
}
case Speaker:
{
stack = new ItemStack( this, quantity, 5 );
break;
}
default:
{
// Ignore types we can't handle
return ItemStack.EMPTY;
}
}
if( label != null )
{
@ -93,29 +86,30 @@ public PeripheralType getPeripheralType( int damage )
{
case 0:
default:
{
return PeripheralType.DiskDrive;
}
case 1:
{
return PeripheralType.WirelessModem;
}
case 2:
{
return PeripheralType.Monitor;
}
case 3:
{
return PeripheralType.Printer;
}
case 4:
{
return PeripheralType.AdvancedMonitor;
}
case 5:
{
return PeripheralType.Speaker;
}
}
}
@Nonnull
@Override
public EnumActionResult onItemUse( EntityPlayer player, World world, @Nonnull BlockPos pos, @Nonnull EnumHand hand, @Nonnull EnumFacing facing, float hitX, float hitY, float hitZ )
{
if( getPeripheralType( player.getHeldItem( hand ) ) == PeripheralType.WirelessModem )
{
EnumActionResult result = MCMPHooks.onItemUse( this, player, world, pos, hand, facing, hitX, hitY, hitZ );
if( result != EnumActionResult.PASS ) return result;
}
return super.onItemUse( player, world, pos, hand, facing, hitX, hitY, hitZ );
}
}

View File

@ -7,13 +7,20 @@
package dan200.computercraft.shared.peripheral.modem.wireless;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.integration.mcmp.MCMPHooks;
import dan200.computercraft.shared.peripheral.PeripheralType;
import dan200.computercraft.shared.peripheral.common.ItemPeripheralBase;
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
import net.minecraft.block.Block;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -39,4 +46,14 @@ public PeripheralType getPeripheralType( int damage )
{
return PeripheralType.AdvancedModem;
}
@Nonnull
@Override
public EnumActionResult onItemUse( EntityPlayer player, World worldIn, @Nonnull BlockPos pos, @Nonnull EnumHand hand, @Nonnull EnumFacing facing, float hitX, float hitY, float hitZ )
{
EnumActionResult result = MCMPHooks.onItemUse( this, player, worldIn, pos, hand, facing, hitX, hitY, hitZ );
if( result != EnumActionResult.PASS ) return result;
return super.onItemUse( player, worldIn, pos, hand, facing, hitX, hitY, hitZ );
}
}