|
7 | 7 | import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour; |
8 | 8 | import dev.ryanhcode.sable.ActiveSableCompanion; |
9 | 9 | import dev.ryanhcode.sable.Sable; |
| 10 | +import dev.ryanhcode.sable.companion.math.JOMLConversion; |
10 | 11 | import dev.ryanhcode.sable.neoforge.mixinhelper.compatibility.create.block_breakers.SubLevelBlockBreakingUtility; |
11 | 12 | import dev.ryanhcode.sable.sublevel.SubLevel; |
| 13 | +import net.createmod.catnip.math.VecHelper; |
| 14 | +import net.createmod.catnip.nbt.NBTHelper; |
12 | 15 | import net.minecraft.core.BlockPos; |
13 | 16 | import net.minecraft.nbt.CompoundTag; |
14 | 17 | import net.minecraft.nbt.NbtUtils; |
| 18 | +import net.minecraft.nbt.Tag; |
| 19 | +import net.minecraft.world.damagesource.DamageSource; |
15 | 20 | import net.minecraft.world.level.Level; |
16 | 21 | import net.minecraft.world.level.block.state.BlockState; |
17 | 22 | import net.minecraft.world.phys.Vec3; |
| 23 | +import org.joml.Vector3d; |
18 | 24 | import org.spongepowered.asm.mixin.Mixin; |
19 | 25 | import org.spongepowered.asm.mixin.Shadow; |
20 | 26 | import org.spongepowered.asm.mixin.injection.At; |
@@ -50,45 +56,60 @@ public abstract class BlockBreakingMovementBehaviourMixin implements MovementBeh |
50 | 56 | original.call(context, breakingPosWSublevel); |
51 | 57 | } |
52 | 58 | } |
53 | | - } |
54 | 59 |
|
55 | | - @Inject(method = "tick", at = @At("HEAD"), cancellable = true) |
56 | | - public void sable$testBreakingPosDist(final MovementContext context, final CallbackInfo ci) { |
57 | | - final CompoundTag data = context.data; |
58 | | - if (data.contains("BreakingPos") || data.contains("LastPos")) { |
59 | | - final BlockPos blockPos = NbtUtils.readBlockPos(data, "BreakingPos").orElseGet(() -> NbtUtils.readBlockPos(data, "LastPos").orElse(null)); |
| 60 | + //make sure we're actually starting to break something |
| 61 | + if (context.stall && (context.data.contains("BreakingPos"))) { |
| 62 | + final Vector3d checkPos = JOMLConversion.toJOML(context.position); |
60 | 63 |
|
61 | | - if (blockPos != null) { |
62 | | - final Vec3 localCenter = context.localPos.getCenter(); |
| 64 | + //project our position into the real world |
| 65 | + final SubLevel parentSublevel = Sable.HELPER.getContaining(context.world, context.position); |
| 66 | + if (parentSublevel != null) { |
| 67 | + parentSublevel.logicalPose().transformPosition(checkPos); |
| 68 | + } |
| 69 | + |
| 70 | + //project our position into the target's plot |
| 71 | + final SubLevel targetSublevel = Sable.HELPER.getContaining(context.world, NbtUtils.readBlockPos(context.data, "BreakingPos").orElseThrow()); |
| 72 | + if (targetSublevel != null) { |
| 73 | + targetSublevel.logicalPose().transformPositionInverse(checkPos); |
| 74 | + } |
63 | 75 |
|
64 | | - Vec3 sublevelLocalCenter = context.contraption.entity.toGlobalVector(localCenter, 1); |
65 | | - Vec3 targetCenter = blockPos.getCenter(); |
| 76 | + //save the current projected position to check movement distance against |
| 77 | + context.data.put("ProjectedPos", VecHelper.writeNBT(JOMLConversion.toMojang(checkPos))); |
| 78 | + } |
| 79 | + } |
66 | 80 |
|
67 | | - final ActiveSableCompanion helper = Sable.HELPER; |
68 | | - final SubLevel parentSublevel = helper.getContaining(context.world, context.contraption.anchor); |
69 | | - final SubLevel targetSubLevel = helper.getContaining(context.world, blockPos); |
| 81 | + @Inject(method = "cancelStall", at = @At("TAIL")) |
| 82 | + public void sable$removeProjected(final MovementContext context, final CallbackInfo ci) { |
| 83 | + context.data.remove("ProjectedPos"); |
| 84 | + } |
70 | 85 |
|
71 | | - if (parentSublevel != null) { |
72 | | - sublevelLocalCenter = parentSublevel.logicalPose().transformPosition(sublevelLocalCenter); |
73 | | - } |
| 86 | + @Inject(method = "tick", at = @At("HEAD"), cancellable = true) |
| 87 | + public void sable$testProjectedPosDist(final MovementContext context, final CallbackInfo ci) { |
| 88 | + final CompoundTag data = context.data; |
74 | 89 |
|
75 | | - if (targetSubLevel != null) { |
76 | | - targetCenter = targetSubLevel.logicalPose().transformPosition(targetCenter); |
77 | | - } |
| 90 | + //kind of a work-around to not require injecting into every place where BreakingPos is removed. |
| 91 | + if (!context.data.contains("BreakingPos")) { |
| 92 | + data.remove("ProjectedPos"); |
| 93 | + return; |
| 94 | + } |
78 | 95 |
|
79 | | - if (sublevelLocalCenter.distanceToSqr(targetCenter) > 2 * 2) { |
80 | | - data.remove("Progress"); |
81 | | - data.remove("TicksUntilNextProgress"); |
82 | | - data.remove("BreakingPos"); |
83 | | - data.remove("LastPos"); |
84 | | - data.remove("WaitingTicks"); |
| 96 | + final Vec3 sublevelLocalCenter = context.contraption.entity.toGlobalVector(context.localPos.getCenter(), 1); |
| 97 | + if (data.contains("ProjectedPos") && Sable.HELPER.distanceSquaredWithSubLevels(context.world, VecHelper.readNBT(data.getList("ProjectedPos", Tag.TAG_DOUBLE)), sublevelLocalCenter) > 2*2) { |
| 98 | + final BlockPos blockPos = NbtUtils.readBlockPos(data, "BreakingPos").orElse(null); |
85 | 99 |
|
86 | | - context.stall = false; |
87 | | - context.world.destroyBlockProgress(data.getInt("BreakerId"), blockPos, -1); |
| 100 | + data.remove("Progress"); |
| 101 | + data.remove("TicksUntilNextProgress"); |
| 102 | + data.remove("BreakingPos"); |
| 103 | + data.remove("LastPos"); |
| 104 | + data.remove("WaitingTicks"); |
| 105 | + data.remove("ProjectedPos"); |
88 | 106 |
|
89 | | - ci.cancel(); |
90 | | - } |
| 107 | + context.stall = false; |
| 108 | + if (blockPos != null) { |
| 109 | + context.world.destroyBlockProgress(data.getInt("BreakerId"), blockPos, -1); |
91 | 110 | } |
| 111 | + |
| 112 | + ci.cancel(); |
92 | 113 | } |
93 | 114 | } |
94 | 115 | } |
0 commit comments