Skip to content

Commit

Permalink
Architecture Craft + TOP Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
IntegerLimit committed Apr 27, 2024
1 parent 1c2abfc commit 700bf95
Showing 7 changed files with 218 additions and 3 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -254,7 +254,7 @@ enable_xu2 = false
# If this is set to false, the mixin will not apply.
enable_rocketry = false

# Whether to enable Architecture Craft in runtime. Enables the mixin which adds more Architecture Craft Slopes, improves the Sawbench UI, and fixes the Sawbench Particle Texture.
# Whether to enable Architecture Craft in runtime. Enables the mixin which adds more Architecture Craft Slopes, improves the Sawbench UI, fixes the Sawbench Particle Texture, and fixes Shapes' Harvest Tools and Levels in The One Probe.
# If this is set to false, the mixin will not apply.
enable_architecture_craft = false

2 changes: 1 addition & 1 deletion src/main/java/com/nomiceu/nomilabs/config/LabsConfig.java
Original file line number Diff line number Diff line change
@@ -206,7 +206,7 @@ public static class ModIntegration {
public boolean enableAdvancedRocketryIntegration = true;

@Config.Comment({
"Whether to enable ArchitectureCraft Integration, which adds new slope variants, improves the GUI of the Sawbench, and fixes the Sawbench Particle Texture.",
"Whether to enable ArchitectureCraft Integration, which adds new slope variants, improves the GUI of the Sawbench, fixes the Sawbench Particle Texture, and fixes Shapes' Harvest Tools and Levels in The One Probe.",
"[default: true]" })
@Config.LangKey("config.nomilabs.mod_integration.architecture_craft")
@Config.RequiresMcRestart
3 changes: 2 additions & 1 deletion src/main/java/com/nomiceu/nomilabs/core/LabsLateMixin.java
Original file line number Diff line number Diff line change
@@ -42,7 +42,8 @@ public class LabsLateMixin implements ILateMixinLoader {
new AbstractMap.SimpleImmutableEntry<>(LabsValues.FTB_UTILS_MODID,
LabsConfig.modIntegration.enableFTBUtilsIntegration),
new AbstractMap.SimpleImmutableEntry<>(LabsValues.TOP_ADDONS_MODID,
LabsConfig.modIntegration.enableTopAddonsIntegration))
LabsConfig.modIntegration.enableTopAddonsIntegration),
new AbstractMap.SimpleImmutableEntry<>(LabsValues.TOP_MODID, true))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

@Override
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.nomiceu.nomilabs.mixin.architecturecraft;

import com.elytradev.architecture.common.block.BlockArchitecture;
import com.elytradev.architecture.common.block.BlockShape;
import com.elytradev.architecture.common.tile.TileShape;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

/**
* Improves Determining Whether the Shape can be Harvested, and the Hardness of the Shape.
*/
@Mixin(value = BlockShape.class, remap = false)
public class BlockShapeMixin extends BlockArchitecture<TileShape> {
/**
* Default Ignored Constructor
*/
public BlockShapeMixin(Material material) {
super(material);
}

@Inject(method = "acBlockStrength", at = @At(value = "INVOKE", target = "Lcom/elytradev/architecture/common/block/BlockShape;acCanHarvestBlock(Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/entity/player/EntityPlayer;)Z"), cancellable = true)
private static void baseBlockStrength(IBlockState state, EntityPlayer player, World world, BlockPos pos, CallbackInfoReturnable<Float> cir, @Local(ordinal = 1) float strength) {
cir.setReturnValue(state.getBlock().canHarvestBlock(world, pos, player) ? strength / 100.0F : strength / 30.0F);
}

/**
* Modified from {@link net.minecraftforge.common.ForgeHooks#canHarvestBlock(Block, EntityPlayer, IBlockAccess, BlockPos)}
*/
@SuppressWarnings("DuplicatedCode")
@Override
public boolean canHarvestBlock(@NotNull IBlockAccess world, @NotNull BlockPos pos, @NotNull EntityPlayer player) {
var te = TileShape.get(world, pos);
if (te == null) return super.canHarvestBlock(world, pos, player);

var baseState = te.getBaseBlockState();
var baseBlock = baseState.getBlock();

if (baseState.getMaterial().isToolNotRequired()) {
return true;
}

ItemStack stack = player.getHeldItemMainhand();
String tool = baseBlock.getHarvestTool(baseState);
if (stack.isEmpty() || tool == null)
return player.canHarvestBlock(baseState);

int toolLevel = stack.getItem().getHarvestLevel(stack, tool, player, baseState);
if (toolLevel < 0)
return player.canHarvestBlock(baseState);

return toolLevel >= baseBlock.getHarvestLevel(baseState);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package com.nomiceu.nomilabs.mixin.theoneprobe;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTool;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Loader;

import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import com.llamalad7.mixinextras.sugar.Local;
import com.llamalad7.mixinextras.sugar.ref.LocalIntRef;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import com.nomiceu.nomilabs.LabsValues;
import com.nomiceu.nomilabs.config.LabsConfig;

import mcjty.theoneprobe.api.IProbeInfo;
import mcjty.theoneprobe.apiimpl.providers.HarvestInfoTools;

/**
* Fixes Architecture Craft Shapes' Displays on TOP.
* As far as I can see, no API to change this outside of mixins.
*/
@Mixin(value = HarvestInfoTools.class, remap = false)
public class HarvestInfoToolsMixin {

@Shadow
@Final
private static HashMap<String, ItemStack> testTools;

/**
* Only change the main `showHarvestInfo` method.
* This is called using the normal configs. The other two methods are only called on some specific configurations.
* <p>
* `showCanBeHarvested` displays correct results.
* `showHarvestLevel` does not provide world or position.
*/
@Inject(method = "showHarvestInfo",
at = @At(value = "INVOKE_ASSIGN",
target = "Lnet/minecraft/block/Block;getHarvestTool(Lnet/minecraft/block/state/IBlockState;)Ljava/lang/String;"))
private static void getHarvestToolForArchitectureCraft(IProbeInfo probeInfo, World world, BlockPos pos, Block block,
IBlockState blockState, EntityPlayer player, CallbackInfo ci,
@Local LocalRef<String> harvestTool) {
if (!Loader.isModLoaded(LabsValues.ARCHITECTURE_MODID) ||
!LabsConfig.modIntegration.enableArchitectureCraftIntegration || isNotShapeForArchitectureCraft(block))
return;

var baseBlockState = getBaseBlockStateForArchitectureCraft(world, pos);
if (baseBlockState == null) return;

var retrievedHarvestTool = baseBlockState.getBlock().getHarvestTool(baseBlockState);

// From the Original Function
if (retrievedHarvestTool == null) {
// The block doesn't have an explicitly-set harvest tool, so test our wooden tools against it
float blockHardness = baseBlockState.getBlockHardness(world, pos);
if (blockHardness > 0f) {
for (Map.Entry<String, ItemStack> testToolEntry : testTools.entrySet()) {
// loop through our test tools until we find a winner.
ItemStack testTool = testToolEntry.getValue();

if (testTool != null && testTool.getItem() instanceof ItemTool toolItem) {
if (testTool.getDestroySpeed(baseBlockState) >= toolItem.toolMaterial.getEfficiency()) {
retrievedHarvestTool = testToolEntry.getKey();
break;
}
}
}
}
}
harvestTool.set(retrievedHarvestTool);
}

@Inject(method = "showHarvestInfo",
at = @At(value = "INVOKE_ASSIGN",
target = "Lnet/minecraft/block/Block;getHarvestLevel(Lnet/minecraft/block/state/IBlockState;)I"))
private static void getHarvestLevelForArchitectureCraft(IProbeInfo probeInfo, World world, BlockPos pos,
Block block, IBlockState blockState, EntityPlayer player,
CallbackInfo ci, @Local LocalIntRef harvestLevel) {
if (!Loader.isModLoaded(LabsValues.ARCHITECTURE_MODID) ||
!LabsConfig.modIntegration.enableArchitectureCraftIntegration || isNotShapeForArchitectureCraft(block))
return;

var baseBlockState = getBaseBlockStateForArchitectureCraft(world, pos);
if (baseBlockState == null) return;
harvestLevel.set(baseBlockState.getBlock().getHarvestLevel(baseBlockState));
}

/**
* Use Reflection to prevent hard dep. Equivalent to `!(block instanceof BlockShape)`.
*/
@Unique
private static boolean isNotShapeForArchitectureCraft(Block block) {
try {
var shapeClass = Class.forName("com.elytradev.architecture.common.block.BlockShape");
return !shapeClass.isInstance(block);
} catch (ClassNotFoundException e) {
return true;
}
}

/**
* Use Reflection to prevent hard dep. Equivalent to `TileShape.get(world, pos).getBaseBlockState()`.
*/
@Unique
@Nullable
private static IBlockState getBaseBlockStateForArchitectureCraft(World world, BlockPos pos) {
try {
var tileShapeClass = Class.forName("com.elytradev.architecture.common.tile.TileShape");
var getTileMethod = tileShapeClass.getDeclaredMethod("get", IBlockAccess.class, BlockPos.class);
var tile = getTileMethod.invoke(null, world, pos);
if (tile == null) return null;

var getBaseBlockStateMethod = tile.getClass().getDeclaredMethod("getBaseBlockState");
return (IBlockState) getBaseBlockStateMethod.invoke(tile);
} catch (ClassNotFoundException | IllegalAccessException | NoSuchMethodException |
InvocationTargetException e) {
return null;
}
}
}
1 change: 1 addition & 0 deletions src/main/resources/mixins.nomilabs.architecturecraft.json
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
"compatibilityLevel": "JAVA_8",
"mixins": [
"BlockSawbenchMixin",
"BlockShapeMixin",
"ShapeAccessor",
"TileSawbenchMixin"
],
12 changes: 12 additions & 0 deletions src/main/resources/mixins.nomilabs.theoneprobe.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"package": "com.nomiceu.nomilabs.mixin.theoneprobe",
"refmap": "mixins.nomilabs.refmap.json",
"target": "@env(DEFAULT)",
"minVersion": "0.8",
"compatibilityLevel": "JAVA_8",
"mixins": [
"HarvestInfoToolsMixin"
],
"client": [],
"server": []
}

0 comments on commit 700bf95

Please sign in to comment.