diff --git a/build.gradle b/build.gradle index 4e5524725..c55cbaf7e 100644 --- a/build.gradle +++ b/build.gradle @@ -53,6 +53,9 @@ minecraft { property 'forge.logging.markers', 'REGISTRIES' property 'forge.logging.console.level', 'debug' + property 'mixin.env.remapRefMap', 'true' + property 'mixin.env.refMapRemappingFile', "${buildDir}/createSrgToMcp/output.srg" + mods { computercraft { source sourceSets.main @@ -138,6 +141,7 @@ dependencies { compileOnly fg.deobf("mezz.jei:jei-1.16.5:7.7.0.104:api") compileOnly fg.deobf("com.blamejared.crafttweaker:CraftTweaker-1.16.5:7.1.0.313") + compileOnly fg.deobf("commoble.morered:morered-1.16.5:2.1.1.0") runtimeOnly fg.deobf("mezz.jei:jei-1.16.5:7.7.0.104") @@ -180,12 +184,12 @@ task luaJavadoc(type: Javadoc) { jar { manifest { - attributes(["Specification-Title": "computercraft", - "Specification-Vendor": "SquidDev", - "Specification-Version": "1", - "Implementation-Title": "CC: Tweaked", - "Implementation-Version": "${mod_version}", - "Implementation-Vendor" :"SquidDev", + attributes(["Specification-Title" : "computercraft", + "Specification-Vendor" : "SquidDev", + "Specification-Version" : "1", + "Implementation-Title" : "CC: Tweaked", + "Implementation-Version" : "${mod_version}", + "Implementation-Vendor" : "SquidDev", "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")]) } @@ -211,7 +215,7 @@ processResources { ["git", "-C", projectDir, "log", "--format=tformat:%an%n%cn"].execute().text.split('\n').each { if (!blacklist.contains(it)) contributors.add(it) } - } catch(Exception e) { + } catch (Exception e) { e.printStackTrace() } inputs.property "commithash", hash @@ -221,8 +225,8 @@ processResources { include 'data/computercraft/lua/rom/help/credits.txt' expand 'version': mod_version, - 'mcversion': mc_version, - 'gitcontributors': contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n') + 'mcversion': mc_version, + 'gitcontributors': contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n') } from(sourceSets.main.resources.srcDirs) { @@ -233,6 +237,9 @@ processResources { // Web tasks + +import com.hierynomus.gradle.license.tasks.LicenseCheck +import com.hierynomus.gradle.license.tasks.LicenseFormat import org.apache.tools.ant.taskdefs.condition.Os List mkCommand(String command) { @@ -302,10 +309,6 @@ jacocoTestReport { check.dependsOn jacocoTestReport - -import com.hierynomus.gradle.license.tasks.LicenseCheck -import com.hierynomus.gradle.license.tasks.LicenseFormat - license { mapping("java", "SLASHSTAR_STYLE") strictCheck true @@ -335,8 +338,8 @@ gradle.projectsEvaluated { } -task licenseAPI(type: LicenseCheck); -task licenseFormatAPI(type: LicenseFormat); +task licenseAPI(type: LicenseCheck) +task licenseFormatAPI(type: LicenseFormat) [licenseAPI, licenseFormatAPI].forEach { it.configure { source = sourceSets.main.java @@ -432,7 +435,7 @@ task checkRelease { ok = false project.logger.error("Must mention the changelog in whatsnew.txt") } else { - whatsnew = whatsnew.getAt(0 ..< idx) + whatsnew = whatsnew.getAt(0.. providers = new LinkedHashSet<>(); + private static final ArrayList providers = new ArrayList<>(); private BundledRedstone() {} public static synchronized void register( @Nonnull IBundledRedstoneProvider provider ) { Objects.requireNonNull( provider, "provider cannot be null" ); - providers.add( provider ); + if( !providers.contains( provider ) ) providers.add( provider ); } public static int getDefaultOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side ) diff --git a/src/main/java/dan200/computercraft/shared/Registry.java b/src/main/java/dan200/computercraft/shared/Registry.java index 6c14d93b4..4b18fa6b8 100644 --- a/src/main/java/dan200/computercraft/shared/Registry.java +++ b/src/main/java/dan200/computercraft/shared/Registry.java @@ -25,6 +25,7 @@ import dan200.computercraft.shared.computer.recipe.ComputerUpgradeRecipe; import dan200.computercraft.shared.data.BlockNamedEntityLootCondition; import dan200.computercraft.shared.data.HasComputerIdLootCondition; import dan200.computercraft.shared.data.PlayerCreativeLootCondition; +import dan200.computercraft.shared.integration.morered.MoreRedIntegration; import dan200.computercraft.shared.media.items.ItemDisk; import dan200.computercraft.shared.media.items.ItemPrintout; import dan200.computercraft.shared.media.items.ItemTreasureDisk; @@ -85,6 +86,7 @@ import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fml.DeferredWorkQueue; +import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; @@ -387,6 +389,9 @@ public final class Registry ComputerCraftAPI.registerGenericCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY ); ComputerCraftAPI.registerGenericCapability( CapabilityEnergy.ENERGY ); ComputerCraftAPI.registerGenericCapability( CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY ); + + // Mod integration code. + if( ModList.get().isLoaded( MoreRedIntegration.MOD_ID ) ) MoreRedIntegration.initialise(); } public static void registerLoot() diff --git a/src/main/java/dan200/computercraft/shared/integration/morered/MoreRedIntegration.java b/src/main/java/dan200/computercraft/shared/integration/morered/MoreRedIntegration.java new file mode 100644 index 000000000..1570bd9d1 --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/integration/morered/MoreRedIntegration.java @@ -0,0 +1,124 @@ +/* + * This file is part of ComputerCraft - http://www.computercraft.info + * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission. + * Send enquiries to dratcliffe@gmail.com + */ +package dan200.computercraft.shared.integration.morered; + +import commoble.morered.api.ChanneledPowerSupplier; +import commoble.morered.api.MoreRedAPI; +import dan200.computercraft.ComputerCraft; +import dan200.computercraft.api.ComputerCraftAPI; +import dan200.computercraft.shared.common.IBundledRedstoneBlock; +import dan200.computercraft.shared.util.CapabilityUtil; +import dan200.computercraft.shared.util.FixedPointTileEntityType; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.event.AttachCapabilitiesEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class MoreRedIntegration +{ + public static final String MOD_ID = "morered"; + + private static final ResourceLocation ID = new ResourceLocation( ComputerCraft.MOD_ID, "morered" ); + + private static final class BundledPowerSupplier implements ICapabilityProvider, ChanneledPowerSupplier + { + private final IBundledRedstoneBlock block; + private final TileEntity tile; + private LazyOptional instance; + + private BundledPowerSupplier( IBundledRedstoneBlock block, TileEntity tile ) + { + this.block = block; + this.tile = tile; + } + + @Nonnull + @Override + public LazyOptional getCapability( @Nonnull Capability cap, @Nullable Direction side ) + { + if( cap != MoreRedAPI.CHANNELED_POWER_CAPABILITY ) return LazyOptional.empty(); + + if( tile.isRemoved() || !block.getBundledRedstoneConnectivity( tile.getLevel(), tile.getBlockPos(), side ) ) + { + return LazyOptional.empty(); + } + + return (instance == null ? (instance = LazyOptional.of( () -> this )) : instance).cast(); + } + + @Override + public int getPowerOnChannel( @Nonnull World world, @Nonnull BlockPos wirePos, @Nonnull BlockState wireState, @Nullable Direction wireFace, int channel ) + { + if( wireFace == null ) return 0; + + BlockPos pos = wirePos.relative( wireFace ); + BlockState state = world.getBlockState( pos ); + if( !(state.getBlock() instanceof IBundledRedstoneBlock) ) return 0; + + IBundledRedstoneBlock block = (IBundledRedstoneBlock) state.getBlock(); + return (block.getBundledRedstoneOutput( world, pos, wireFace.getOpposite() ) & (1 << channel)) != 0 ? 31 : 0; + } + + void invalidate() + { + instance = CapabilityUtil.invalidate( instance ); + } + } + + @SubscribeEvent + public static void attachBlockCapabilities( AttachCapabilitiesEvent event ) + { + TileEntity tile = event.getObject(); + if( !(tile.getType() instanceof FixedPointTileEntityType) ) return; + + Block block = ((FixedPointTileEntityType) tile.getType()).getBlock(); + if( !(block instanceof IBundledRedstoneBlock) ) return; + + BundledPowerSupplier provider = new BundledPowerSupplier( (IBundledRedstoneBlock) block, tile ); + event.addCapability( ID, provider ); + event.addListener( provider::invalidate ); + } + + public static void initialise() + { + MinecraftForge.EVENT_BUS.register( MoreRedIntegration.class ); + ComputerCraftAPI.registerBundledRedstoneProvider( MoreRedIntegration::getBundledPower ); + } + + private static int getBundledPower( World world, BlockPos pos, Direction side ) + { + TileEntity tile = world.getBlockEntity( pos ); + if( tile == null ) return -1; + + ChanneledPowerSupplier power = CapabilityUtil.unwrapUnsafe( tile.getCapability( MoreRedAPI.CHANNELED_POWER_CAPABILITY, side ) ); + if( power == null ) return -1; + + BlockState state = tile.getBlockState(); + + // Skip ones already handled by CC. We can do this more efficiently. + if( state.getBlock() instanceof IBundledRedstoneBlock ) return -1; + + int mask = 0; + for( int i = 0; i < 16; i++ ) + { + mask |= power.getPowerOnChannel( world, pos, state, side, i ) > 0 ? (1 << i) : 0; + } + + return mask; + } +} diff --git a/src/main/java/dan200/computercraft/shared/util/CapabilityUtil.java b/src/main/java/dan200/computercraft/shared/util/CapabilityUtil.java index baed8c497..e542294d5 100644 --- a/src/main/java/dan200/computercraft/shared/util/CapabilityUtil.java +++ b/src/main/java/dan200/computercraft/shared/util/CapabilityUtil.java @@ -43,4 +43,10 @@ public final class CapabilityUtil p.addListener( invalidate ); return p.orElseThrow( NullPointerException::new ); } + + @Nullable + public static T unwrapUnsafe( LazyOptional p ) + { + return !p.isPresent() ? null : p.orElseThrow( NullPointerException::new ); + } } diff --git a/src/main/java/dan200/computercraft/shared/util/FixedPointTileEntityType.java b/src/main/java/dan200/computercraft/shared/util/FixedPointTileEntityType.java index 2eb921f20..066cfcac3 100644 --- a/src/main/java/dan200/computercraft/shared/util/FixedPointTileEntityType.java +++ b/src/main/java/dan200/computercraft/shared/util/FixedPointTileEntityType.java @@ -40,6 +40,11 @@ public final class FixedPointTileEntityType extends TileEn return block == this.block.get(); } + public Block getBlock() + { + return block.get(); + } + private static final class FixedPointSupplier implements Supplier { final FixedPointTileEntityType factory;