forked from Draylar/magna
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Account for exterior block hardness in break speed
Players were able to cheese hard block collection by surrounding hard blocks with softer blocks. For example, it was possible to mine up to 8 obsidian at cobblestone break-speed by targeting cobblestone when breaking. To solve this, a new `AbstractBlockState` mixin was introduced. I tried to solve this at other levels (preferably without a mixin), but wasn't able to get all the necessary information anywhere other than at the BlockState level. The minimal breaking delta (which is effectively the same as maximum block hardness) is used instead of the targeted block hardness. Using the average basically didn't solve the issue—it was possible to surround a hard block with softer blocks to 'dilute' the hardness. Fixes Draylar#14 Signed-off-by: Clark Fischer <clark.fischer@gmail.com>
- Loading branch information
Showing
3 changed files
with
78 additions
and
2 deletions.
There are no files selected for viewing
62 changes: 62 additions & 0 deletions
62
src/main/java/dev/draylar/magna/mixin/AbstractBlockStateMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package dev.draylar.magna.mixin; | ||
|
||
import dev.draylar.magna.api.MagnaTool; | ||
import net.minecraft.block.AbstractBlock; | ||
import net.minecraft.block.BlockState; | ||
import net.minecraft.entity.player.PlayerEntity; | ||
import net.minecraft.item.ItemStack; | ||
import net.minecraft.util.math.BlockPos; | ||
import net.minecraft.world.BlockView; | ||
import net.minecraft.world.World; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
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.CallbackInfoReturnable; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* A mixin that calculates the block breaking delta for {@link MagnaTool MagnaTool}s. | ||
*/ | ||
@Mixin(AbstractBlock.AbstractBlockState.class) | ||
public class AbstractBlockStateMixin { | ||
/** | ||
* Compute the block breaking delta for {@link MagnaTool}s. If the held item is not a MagnaTool, this mixin | ||
* does nothing. | ||
* | ||
* <p>The delta is computed by taking the minimum delta of the affected blocks. Mining speed is effectively limited | ||
* by the hardest block being broken. | ||
*/ | ||
@Inject( | ||
method = "calcBlockBreakingDelta", | ||
at = @At("HEAD"), | ||
cancellable = true | ||
) | ||
public void calcBlockBreakingDelta(PlayerEntity player, BlockView world, BlockPos pos, CallbackInfoReturnable<Float> cir) { | ||
ItemStack stack = player.getInventory().getMainHandStack(); | ||
if (stack.getItem() instanceof MagnaTool tool) { | ||
cir.cancel(); | ||
int radius = tool.getRadius(stack); | ||
cir.setReturnValue(calculateDelta(tool, player, radius)); | ||
} | ||
} | ||
|
||
@Unique | ||
private static float calculateDelta(final MagnaTool tool, final PlayerEntity player, final int radius) { | ||
World world = player.getWorld(); | ||
|
||
// Even though we already have the BlockPosition that the player is targeting, the side information wasn't | ||
// passed along, which is necessary for figuring out how to expand the radius. Just throw that away and | ||
// recompute. | ||
List<BlockPos> blocks = tool.getBlockFinder().findPositions(world, player, radius); | ||
|
||
return blocks.stream() | ||
.map(pos -> { | ||
BlockState state = world.getBlockState(pos); | ||
//noinspection deprecation | ||
return state.getBlock().calcBlockBreakingDelta(state, player, world, pos); | ||
}) | ||
.min(Float::compare).orElseThrow(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters