diff options
Diffstat (limited to 'src')
31 files changed, 1489 insertions, 4 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index 05c7fb1e..f1eb4321 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -11,6 +11,7 @@ import de.hysky.skyblocker.skyblock.chat.ChatRuleAnnouncementScreen; import de.hysky.skyblocker.skyblock.chat.ChatRulesHandler; import de.hysky.skyblocker.skyblock.chocolatefactory.EggFinder; import de.hysky.skyblocker.skyblock.chocolatefactory.TimeTowerReminder; +import de.hysky.skyblocker.skyblock.crimson.dojo.DojoManager; import de.hysky.skyblocker.skyblock.crimson.kuudra.Kuudra; import de.hysky.skyblocker.skyblock.dungeon.*; import de.hysky.skyblocker.skyblock.dungeon.partyfinder.PartyFinderScreen; @@ -36,6 +37,7 @@ import de.hysky.skyblocker.skyblock.item.tooltip.BackpackPreview; import de.hysky.skyblocker.skyblock.item.tooltip.ItemTooltip; import de.hysky.skyblocker.skyblock.item.tooltip.TooltipManager; import de.hysky.skyblocker.skyblock.itemlist.ItemRepository; +import de.hysky.skyblocker.skyblock.mayors.JerryTimer; import de.hysky.skyblocker.skyblock.profileviewer.ProfileViewerScreen; import de.hysky.skyblocker.skyblock.rift.TheRift; import de.hysky.skyblocker.skyblock.searchoverlay.SearchOverManager; @@ -181,8 +183,10 @@ public class SkyblockerMod implements ClientModInitializer { ApiUtils.init(); Debug.init(); Kuudra.init(); + DojoManager.init(); RenderHelper.init(); FancyStatusBars.init(); + SkyblockInventoryScreen.initEquipment(); EventNotifications.init(); containerSolverManager.init(); statusBarTracker.init(); @@ -192,6 +196,7 @@ public class SkyblockerMod implements ClientModInitializer { EggFinder.init(); TimeTowerReminder.init(); SkyblockTime.init(); + JerryTimer.init(); TooltipManager.init(); SlotTextManager.init(); diff --git a/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java index fed8fa96..e8127a0e 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java @@ -81,6 +81,68 @@ public class CrimsonIsleCategory { .controller(IntegerFieldControllerBuilder::create) .build()) .build()) - .build(); + //dojo + .group(OptionGroup.createBuilder() + .name(Text.translatable("skyblocker.crimson.dojo")) + .collapsed(false) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.crimson.dojo.forceHelper")) + .description(OptionDescription.of(Text.translatable("skyblocker.crimson.dojo.forceHelper.@Tooltip"))) + .binding(config.crimsonIsle.dojo.enableForceHelper, + () -> config.crimsonIsle.dojo.enableForceHelper, + newValue -> config.crimsonIsle.dojo.enableForceHelper = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.crimson.dojo.staminaHelper")) + .description(OptionDescription.of(Text.translatable("skyblocker.crimson.dojo.staminaHelper.@Tooltip"))) + .binding(config.crimsonIsle.dojo.enableStaminaHelper, + () -> config.crimsonIsle.dojo.enableStaminaHelper, + newValue -> config.crimsonIsle.dojo.enableStaminaHelper = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.crimson.dojo.masteryHelper")) + .description(OptionDescription.of(Text.translatable("skyblocker.crimson.dojo.masteryHelper.@Tooltip"))) + .binding(config.crimsonIsle.dojo.enableMasteryHelper, + () -> config.crimsonIsle.dojo.enableMasteryHelper, + newValue -> config.crimsonIsle.dojo.enableMasteryHelper = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.crimson.dojo.disciplineHelper")) + .description(OptionDescription.of(Text.translatable("skyblocker.crimson.dojo.disciplineHelper.@Tooltip"))) + .binding(config.crimsonIsle.dojo.enableDisciplineHelper, + () -> config.crimsonIsle.dojo.enableDisciplineHelper, + newValue -> config.crimsonIsle.dojo.enableDisciplineHelper = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.crimson.dojo.swiftnessHelper")) + .description(OptionDescription.of(Text.translatable("skyblocker.crimson.dojo.swiftnessHelper.@Tooltip"))) + .binding(config.crimsonIsle.dojo.enableSwiftnessHelper, + () -> config.crimsonIsle.dojo.enableSwiftnessHelper, + newValue -> config.crimsonIsle.dojo.enableSwiftnessHelper = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.crimson.dojo.controlHelper")) + .description(OptionDescription.of(Text.translatable("skyblocker.crimson.dojo.controlHelper.@Tooltip"))) + .binding(config.crimsonIsle.dojo.enableControlHelper, + () -> config.crimsonIsle.dojo.enableControlHelper, + newValue -> config.crimsonIsle.dojo.enableControlHelper = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.crimson.dojo.tenacityHelper")) + .description(OptionDescription.of(Text.translatable("skyblocker.crimson.dojo.tenacityHelper.@Tooltip"))) + .binding(config.crimsonIsle.dojo.enableTenacityHelper, + () -> config.crimsonIsle.dojo.enableTenacityHelper, + newValue -> config.crimsonIsle.dojo.enableTenacityHelper = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .build()) + + .build(); } } diff --git a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java index 9e4935cb..1518dfe7 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java @@ -38,6 +38,20 @@ public class HelperCategory { .build()) .build()) + //Jerry Timer + .group(OptionGroup.createBuilder() + .name(Text.translatable("skyblocker.config.helpers.jerry")) + .collapsed(true) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.config.helpers.jerry.enableJerryTimer")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.helpers.jerry.enableJerryTimer.@Tooltip"))) + .binding(defaults.helpers.jerry.enableJerryTimer, + () -> config.helpers.jerry.enableJerryTimer, + newValue -> config.helpers.jerry.enableJerryTimer = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .build()) + //Experiments Solver .group(OptionGroup.createBuilder() .name(Text.translatable("skyblocker.config.helpers.experiments")) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java index a2a0f815..889b253a 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java @@ -68,6 +68,13 @@ public class UIAndVisualsCategory { newValue -> config.uiAndVisuals.hideStatusEffectOverlay = newValue) .controller(ConfigUtils::createBooleanController) .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.config.uiAndVisuals.showEquipmentInInventory")) + .binding(defaults.uiAndVisuals.showEquipmentInInventory, + () -> config.uiAndVisuals.showEquipmentInInventory, + newValue -> config.uiAndVisuals.showEquipmentInInventory = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) //Chest Value FIXME change dropdown to color controller .group(OptionGroup.createBuilder() diff --git a/src/main/java/de/hysky/skyblocker/config/configs/CrimsonIsleConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/CrimsonIsleConfig.java index 8dd93aee..451d1983 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/CrimsonIsleConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/CrimsonIsleConfig.java @@ -7,6 +7,10 @@ public class CrimsonIsleConfig { @SerialEntry public Kuudra kuudra = new Kuudra(); + @SerialEntry + public Dojo dojo = new Dojo(); + + public static class Kuudra { @SerialEntry public boolean supplyWaypoints = true; @@ -32,4 +36,27 @@ public class CrimsonIsleConfig { @SerialEntry public int arrowPoisonThreshold = 32; } + + public static class Dojo { + @SerialEntry + public boolean enableForceHelper = true; + + @SerialEntry + public boolean enableStaminaHelper = true; + + @SerialEntry + public boolean enableMasteryHelper = true; + + @SerialEntry + public boolean enableDisciplineHelper = true; + + @SerialEntry + public boolean enableSwiftnessHelper = true; + + @SerialEntry + public boolean enableControlHelper = true; + + @SerialEntry + public boolean enableTenacityHelper = true; + } } diff --git a/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java index c0314924..33047f1c 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java @@ -12,6 +12,9 @@ public class HelperConfig { public MythologicalRitual mythologicalRitual = new MythologicalRitual(); @SerialEntry + public Jerry jerry = new Jerry(); + + @SerialEntry public Experiments experiments = new Experiments(); @SerialEntry @@ -28,6 +31,11 @@ public class HelperConfig { public boolean enableMythologicalRitualHelper = true; } + public static class Jerry { + @SerialEntry + public boolean enableJerryTimer = false; + } + public static class Experiments { @SerialEntry public boolean enableChronomatronSolver = true; diff --git a/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java index e016988b..80bdb1c9 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java @@ -28,6 +28,9 @@ public class UIAndVisualsConfig { public boolean hideStatusEffectOverlay = false; @SerialEntry + public boolean showEquipmentInInventory = true; + + @SerialEntry public ChestValue chestValue = new ChestValue(); @SerialEntry diff --git a/src/main/java/de/hysky/skyblocker/events/SkyblockEvents.java b/src/main/java/de/hysky/skyblocker/events/SkyblockEvents.java index c268103d..93426143 100644 --- a/src/main/java/de/hysky/skyblocker/events/SkyblockEvents.java +++ b/src/main/java/de/hysky/skyblocker/events/SkyblockEvents.java @@ -26,6 +26,16 @@ public final class SkyblockEvents { } }); + /** + * Called when the player's Skyblock profile changes. + * @implNote This is called upon receiving the chat message for the profile change rather than the exact moment of profile change, so it may be delayed by a few seconds. + */ + public static final Event<ProfileChange> PROFILE_CHANGE = EventFactory.createArrayBacked(ProfileChange.class, callbacks -> (prev, profile) -> { + for (ProfileChange callback : callbacks) { + callback.onSkyblockProfileChange(prev, profile); + } + }); + @Environment(EnvType.CLIENT) @FunctionalInterface public interface SkyblockJoin { @@ -43,4 +53,10 @@ public final class SkyblockEvents { public interface SkyblockLocationChange { void onSkyblockLocationChange(Location location); } + + @Environment(EnvType.CLIENT) + @FunctionalInterface + public interface ProfileChange { + void onSkyblockProfileChange(String prevProfileId, String profileId); + } } diff --git a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java index 48389d40..7bbbac81 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java @@ -6,6 +6,7 @@ import com.llamalad7.mixinextras.sugar.Local; import de.hysky.skyblocker.skyblock.CompactDamage; import de.hysky.skyblocker.skyblock.FishingHelper; import de.hysky.skyblocker.skyblock.chocolatefactory.EggFinder; +import de.hysky.skyblocker.skyblock.crimson.dojo.DojoManager; import de.hysky.skyblocker.skyblock.dungeon.DungeonScore; import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; import de.hysky.skyblocker.skyblock.end.BeaconHighlighter; @@ -97,6 +98,7 @@ public abstract class ClientPlayNetworkHandlerMixin { @Inject(method = "onParticle", at = @At("RETURN")) private void skyblocker$onParticle(ParticleS2CPacket packet, CallbackInfo ci) { MythologicalRitual.onParticle(packet); + DojoManager.onParticle(packet); EnderNodes.onParticle(packet); } diff --git a/src/main/java/de/hysky/skyblocker/mixins/ClientWorldMixin.java b/src/main/java/de/hysky/skyblocker/mixins/ClientWorldMixin.java new file mode 100644 index 00000000..6c10e5d2 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/mixins/ClientWorldMixin.java @@ -0,0 +1,23 @@ +package de.hysky.skyblocker.mixins; + + +import de.hysky.skyblocker.skyblock.crimson.dojo.DojoManager; +import de.hysky.skyblocker.utils.Utils; +import net.minecraft.block.BlockState; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.util.math.BlockPos; +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.CallbackInfo; + +@Mixin(ClientWorld.class) +public class ClientWorldMixin { + + @Inject(method = "handleBlockUpdate", at = @At("RETURN")) + private void skyblocker$handleBlockUpdate(BlockPos pos, BlockState state, int flags, CallbackInfo ci) { + if (Utils.isInCrimson()) { + DojoManager.onBlockUpdate(pos.toImmutable(), state); + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/mixins/GenericContainerScreenHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixins/GenericContainerScreenHandlerMixin.java index f75af09a..3c3dbd52 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/GenericContainerScreenHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/GenericContainerScreenHandlerMixin.java @@ -2,7 +2,11 @@ package de.hysky.skyblocker.mixins; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.skyblock.dungeon.partyfinder.PartyFinderScreen; +import de.hysky.skyblocker.skyblock.item.SkyblockInventoryScreen; +import de.hysky.skyblocker.utils.Utils; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; import net.minecraft.item.ItemStack; import net.minecraft.screen.GenericContainerScreenHandler; import net.minecraft.screen.ScreenHandler; @@ -22,8 +26,21 @@ public abstract class GenericContainerScreenHandlerMixin extends ScreenHandler { public void setStackInSlot(int slot, int revision, ItemStack stack) { super.setStackInSlot(slot, revision, stack); SkyblockerMod.getInstance().containerSolverManager.markDirty(); - if (MinecraftClient.getInstance().currentScreen instanceof PartyFinderScreen screen) { - screen.markDirty(); + + Screen currentScreen = MinecraftClient.getInstance().currentScreen; + switch (currentScreen) { + case PartyFinderScreen screen -> screen.markDirty(); + case GenericContainerScreen screen when screen.getTitle().getString().toLowerCase().contains("equipment") -> { + int line = slot/9; + if (line > 0 && line < 5 && slot % 9 == 1) { + boolean empty = stack.getName().getString().trim().toLowerCase().startsWith("empty"); + if (Utils.isInTheRift()) + SkyblockInventoryScreen.equipment_rift[line - 1] = empty ? ItemStack.EMPTY : stack; + else + SkyblockInventoryScreen.equipment[line - 1] = empty ? ItemStack.EMPTY : stack; + } + } + case null, default -> {} } } diff --git a/src/main/java/de/hysky/skyblocker/mixins/InventoryScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/InventoryScreenMixin.java index 0d833c22..2194e7a8 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/InventoryScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/InventoryScreenMixin.java @@ -1,11 +1,16 @@ package de.hysky.skyblocker.mixins; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.itemlist.ItemListWidget; import de.hysky.skyblocker.utils.Utils; +import net.minecraft.client.gui.screen.ButtonTextures; import net.minecraft.client.gui.screen.ingame.InventoryScreen; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.TexturedButtonWidget; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -15,4 +20,16 @@ public abstract class InventoryScreenMixin { private RecipeBookWidget skyblocker$replaceRecipeBook(RecipeBookWidget original) { return SkyblockerConfigManager.get().general.itemList.enableItemList && Utils.isOnSkyblock() ? new ItemListWidget() : original; } + + @WrapOperation(method = "init", at = @At(value = "NEW", target = "(IIIILnet/minecraft/client/gui/screen/ButtonTextures;Lnet/minecraft/client/gui/widget/ButtonWidget$PressAction;)Lnet/minecraft/client/gui/widget/TexturedButtonWidget;")) + private TexturedButtonWidget skyblocker$moveButton(int x, int y, int width, int height, ButtonTextures textures, ButtonWidget.PressAction pressAction, Operation<TexturedButtonWidget> original) { + if (!Utils.isOnSkyblock() || !SkyblockerConfigManager.get().uiAndVisuals.showEquipmentInInventory) return original.call(x, y, width, height, textures, pressAction); + return new TexturedButtonWidget(x + 21, y, width, height, textures, pressAction); + } + + @WrapOperation(method = "method_19891", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/ButtonWidget;setPosition(II)V")) + private void skyblocker$moveButtonWhenPressed(ButtonWidget instance, int i, int j, Operation<Void> original) { + if (!Utils.isOnSkyblock() || !SkyblockerConfigManager.get().uiAndVisuals.showEquipmentInInventory) original.call(instance, i, j); + else instance.setPosition(i + 21, j); + } } diff --git a/src/main/java/de/hysky/skyblocker/mixins/MinecraftClientMixin.java b/src/main/java/de/hysky/skyblocker/mixins/MinecraftClientMixin.java index b04f958f..f91ddc86 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/MinecraftClientMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/MinecraftClientMixin.java @@ -1,7 +1,11 @@ package de.hysky.skyblocker.mixins; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.item.HotbarSlotLock; import de.hysky.skyblocker.skyblock.item.ItemProtection; +import de.hysky.skyblocker.skyblock.item.SkyblockInventoryScreen; import de.hysky.skyblocker.utils.JoinWorldPlaceholderScreen; import de.hysky.skyblocker.utils.ReconfiguringPlaceholderScreen; import de.hysky.skyblocker.utils.Utils; @@ -9,8 +13,10 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.DownloadingTerrainScreen; import net.minecraft.client.gui.screen.ReconfiguringScreen; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ingame.InventoryScreen; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.entity.player.PlayerEntity; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -54,4 +60,10 @@ public abstract class MinecraftClientMixin { private Screen modifyJoinWorld(Screen screen) { return Utils.isOnSkyblock() ? new JoinWorldPlaceholderScreen() : screen; } + + @WrapOperation(method = "handleInputEvents", at = @At(value = "NEW", target = "(Lnet/minecraft/entity/player/PlayerEntity;)Lnet/minecraft/client/gui/screen/ingame/InventoryScreen;")) + private InventoryScreen skyblocker$skyblockInventoryScreen(PlayerEntity player, Operation<InventoryScreen> original) { + if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().uiAndVisuals.showEquipmentInInventory) return new SkyblockInventoryScreen(player); + else return original.call(player); + } }
\ No newline at end of file diff --git a/src/main/java/de/hysky/skyblocker/mixins/PingMeasurerMixin.java b/src/main/java/de/hysky/skyblocker/mixins/PingMeasurerMixin.java new file mode 100644 index 00000000..a9fae752 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/mixins/PingMeasurerMixin.java @@ -0,0 +1,22 @@ +package de.hysky.skyblocker.mixins; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import de.hysky.skyblocker.skyblock.crimson.dojo.DojoManager; +import de.hysky.skyblocker.utils.Utils; +import net.minecraft.client.network.PingMeasurer; +import net.minecraft.util.profiler.MultiValueDebugSampleLogImpl; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(PingMeasurer.class) +public class PingMeasurerMixin { + + @WrapOperation(method = "onPingResult", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiler/MultiValueDebugSampleLogImpl;push(J)V")) + private void skyblocker$onPingResult(MultiValueDebugSampleLogImpl log, long ping, Operation<Void> operation) { + if (Utils.isInCrimson()) { + DojoManager.onPingResult(ping); + } + operation.call(log, ping); + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/ControlTestHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/ControlTestHelper.java new file mode 100644 index 00000000..2f616a1e --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/ControlTestHelper.java @@ -0,0 +1,77 @@ +package de.hysky.skyblocker.skyblock.crimson.dojo; + +import de.hysky.skyblocker.utils.render.RenderHelper; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.Entity; +import net.minecraft.entity.mob.WitherSkeletonEntity; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Vec3d; + +import java.awt.*; + +public class ControlTestHelper { + private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); + + private static WitherSkeletonEntity correctWitherSkeleton; + private static Vec3d lastPos; + private static long lastUpdate; + private static Vec3d pingOffset; + private static Vec3d lastPingOffset; + + protected static void reset() { + correctWitherSkeleton = null; + lastPos = null; + lastUpdate = -1; + pingOffset = null; + lastPingOffset = null; + } + + /** + * Find the correct WitherSkeleton entity when it spawns to start tracking it + * + * @param entity spawned entity + */ + protected static void onEntitySpawn(Entity entity) { + if (entity instanceof WitherSkeletonEntity witherSkeleton && correctWitherSkeleton == null) { + correctWitherSkeleton = witherSkeleton; + } + } + + /** + * Finds where to look in 3 ticks effected by ping + */ + protected static void update() { + if (correctWitherSkeleton != null) { + //smoothly adjust the ping throughout the test + if (lastPos != null) { + lastPingOffset = pingOffset; + double ping = DojoManager.ping / 1000d; + //find distance between last position and current position of skeleton + Vec3d movementVector = correctWitherSkeleton.getPos().subtract(lastPos).multiply(1, 0.1, 1); + //adjust the vector to current ping (multiply by 1 + time in second until the next update offset by the players ping) + pingOffset = movementVector.multiply(1 + 3 / 20d + ping); + } + lastPos = correctWitherSkeleton.getPos(); + lastUpdate = System.currentTimeMillis(); + } + } + + /** + * Renders an outline around where the player should aim (assumes values are updated every 3 ticks) + * + * @param context render context + */ + protected static void render(WorldRenderContext context) { + if (CLIENT.player != null && correctWitherSkeleton != null && pingOffset != null && lastPingOffset != null) { + float tickDelta = context.tickCounter().getTickDelta(false); + //how long until net update + double updatePercent = (double) (System.currentTimeMillis() - lastUpdate) / 150; + Vec3d aimPos = correctWitherSkeleton.getEyePos().add(pingOffset.multiply(updatePercent)).add(lastPingOffset.multiply(1 - updatePercent)); + Box targetBox = new B |
