1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-12-14 04:00:30 +00:00

Separate breaking progress for wired modems

This means that if the current player is breaking a cable/wired modem,
only the part they're looking at has breaking progress. Closes #355.

A mixin is definitely not the cleanest way to do this. There's a couple
of alternatives:

 - CodeChickenLib's approach of overriding the BlockRendererDispatcher
   instance with a delegating subclasss. One mod doing this is fine,
   several is Not Great.o

 - Adding a PR to Forge: I started this, and it's definitely the ideal
   solution, but any event for this would have a ton of fields and just
   ended up looking super ugly.
This commit is contained in:
Jonathan Coates 2021-12-13 13:30:43 +00:00
parent 92a0ef2b75
commit 1cfad31a0d
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
3 changed files with 125 additions and 8 deletions

View File

@ -6,6 +6,7 @@ buildscript {
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:5.1.+'
classpath "org.spongepowered:mixingradle:0.7.+"
classpath 'org.parchmentmc:librarian:1.+'
}
}
@ -22,6 +23,7 @@ plugins {
}
apply plugin: 'net.minecraftforge.gradle'
apply plugin: "org.spongepowered.mixin"
apply plugin: 'org.parchmentmc.librarian.forgegradle'
version = mod_version
@ -64,6 +66,8 @@ minecraft {
source sourceSets.main
}
}
arg "-mixin.config=computercraft.mixins.json"
}
client {
@ -109,6 +113,10 @@ minecraft {
accessTransformer file('src/testMod/resources/META-INF/accesstransformer.cfg')
}
mixin {
add sourceSets.main, 'computercraft.mixins.refmap.json'
}
repositories {
mavenCentral()
maven {
@ -130,6 +138,7 @@ dependencies {
checkstyle "com.puppycrawl.tools:checkstyle:8.25"
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
annotationProcessor 'org.spongepowered:mixin:0.8.4:processor'
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")
@ -149,7 +158,7 @@ dependencies {
testModImplementation sourceSets.main.output
cctJavadoc 'cc.tweaked:cct-javadoc:1.4.2'
cctJavadoc 'cc.tweaked:cct-javadoc:1.4.4'
}
// Compile tasks
@ -181,13 +190,16 @@ 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",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")])
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"),
"MixinConfigs" : "computercraft.mixins.json",
])
}
from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }

View File

@ -0,0 +1,92 @@
/*
* 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.mixin;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.peripheral.modem.wired.BlockCable;
import dan200.computercraft.shared.peripheral.modem.wired.CableModemVariant;
import dan200.computercraft.shared.peripheral.modem.wired.CableShapes;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelRenderer;
import net.minecraft.client.renderer.BlockModelShapes;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.IBlockDisplayReader;
import net.minecraftforge.client.model.data.IModelData;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random;
/**
* Provides custom block breaking progress for modems, so it only applies to the current part.
*
* @see BlockRendererDispatcher#renderBlockDamage(BlockState, BlockPos, IBlockDisplayReader, MatrixStack, IVertexBuilder, IModelData)
*/
@Mixin( BlockRendererDispatcher.class )
public class BlockRendererDispatcherMixin
{
@Shadow
private final Random random;
@Shadow
private final BlockModelShapes blockModelShaper;
@Shadow
private final BlockModelRenderer modelRenderer;
public BlockRendererDispatcherMixin( Random random, BlockModelShapes blockModelShaper, BlockModelRenderer modelRenderer )
{
this.random = random;
this.blockModelShaper = blockModelShaper;
this.modelRenderer = modelRenderer;
}
@Inject(
method = "name=/^renderBlockDamage$/ desc=/IModelData;\\)V$/",
at = @At( "HEAD" ),
cancellable = true,
require = 0 // This isn't critical functionality, so don't worry if we can't apply it.
)
public void renderBlockDamage(
BlockState state, BlockPos pos, IBlockDisplayReader world, MatrixStack pose, IVertexBuilder buffers, IModelData modelData,
CallbackInfo info
)
{
// Only apply to cables which have both a cable and modem
if( state.getBlock() != Registry.ModBlocks.CABLE.get()
|| !state.getValue( BlockCable.CABLE )
|| state.getValue( BlockCable.MODEM ) == CableModemVariant.None
)
{
return;
}
RayTraceResult hit = Minecraft.getInstance().hitResult;
if( hit == null || hit.getType() != RayTraceResult.Type.BLOCK ) return;
BlockPos hitPos = ((BlockRayTraceResult) hit).getBlockPos();
if( !hitPos.equals( pos ) ) return;
info.cancel();
BlockState newState = WorldUtil.isVecInside( CableShapes.getModemShape( state ), hit.getLocation().subtract( pos.getX(), pos.getY(), pos.getZ() ) )
? state.getBlock().defaultBlockState().setValue( BlockCable.MODEM, state.getValue( BlockCable.MODEM ) )
: state.setValue( BlockCable.MODEM, CableModemVariant.None );
IBakedModel model = blockModelShaper.getBlockModel( newState );
long seed = newState.getSeed( pos );
modelRenderer.renderModel( world, model, newState, pos, pose, buffers, true, random, seed, OverlayTexture.NO_OVERLAY, modelData );
}
}

View File

@ -0,0 +1,13 @@
{
"minVersion": "0.8",
"required": true,
"compatibilityLevel": "JAVA_8",
"refmap": "computercraft.mixins.refmap.json",
"package": "dan200.computercraft.mixin",
"client": [
"BlockRendererDispatcherMixin"
],
"injectors": {
"defaultRequire": 1
}
}