diff options
author | Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> | 2024-03-14 15:04:20 -0400 |
---|---|---|
committer | Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> | 2024-03-14 15:04:20 -0400 |
commit | e132d040bb9c068a956603863fbb88258e1a41cc (patch) | |
tree | 7d3597c12bdaaf92163debadf2ee6093ed3a07fc | |
parent | 26cf371c823d36bb289577914b3f52ffd4b924d5 (diff) | |
download | Skyblocker-e132d040bb9c068a956603863fbb88258e1a41cc.tar.gz Skyblocker-e132d040bb9c068a956603863fbb88258e1a41cc.tar.bz2 Skyblocker-e132d040bb9c068a956603863fbb88258e1a41cc.zip |
Fix bugs with secret detection
Fix secret item detection with Personal Deleter
Add trapped chest detection for mimics
Add locked chest detection and set secret as missing if chest is locked
Fix translatable text in Room
6 files changed, 74 insertions, 52 deletions
diff --git a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java index 4c414212..df2fcd4f 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java @@ -4,20 +4,16 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.WrapWithCondition; import com.llamalad7.mixinextras.sugar.Local; import de.hysky.skyblocker.skyblock.FishingHelper; -import de.hysky.skyblocker.skyblock.end.TheEnd; import de.hysky.skyblocker.skyblock.dungeon.DungeonScore; -import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; import de.hysky.skyblocker.skyblock.end.BeaconHighlighter; +import de.hysky.skyblocker.skyblock.end.TheEnd; import de.hysky.skyblocker.skyblock.waypoint.MythologicalRitual; import de.hysky.skyblocker.utils.SlayerUtils; import de.hysky.skyblocker.utils.Utils; import net.minecraft.block.Blocks; -import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityStatuses; -import net.minecraft.entity.ItemEntity; -import net.minecraft.entity.LivingEntity; import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.EntityStatusS2CPacket; import net.minecraft.network.packet.s2c.play.ParticleS2CPacket; @@ -27,7 +23,6 @@ import org.slf4j.Logger; 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.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ClientPlayNetworkHandler.class) @@ -42,12 +37,6 @@ public abstract class ClientPlayNetworkHandlerMixin { } } - @ModifyVariable(method = "onItemPickupAnimation", at = @At(value = "STORE", ordinal = 0)) - private ItemEntity skyblocker$onItemPickup(ItemEntity itemEntity, @Local LivingEntity collector) { - DungeonManager.onItemPickup(itemEntity, collector, collector == MinecraftClient.getInstance().player); - return itemEntity; - } - @WrapWithCondition(method = "onEntityPassengersSet", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;)V", remap = false)) private boolean skyblocker$cancelEntityPassengersWarning(Logger instance, String msg) { return !Utils.isOnHypixel(); diff --git a/src/main/java/de/hysky/skyblocker/mixin/ClientWorldMixin.java b/src/main/java/de/hysky/skyblocker/mixin/ClientWorldMixin.java new file mode 100644 index 00000000..836fbcc9 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/mixin/ClientWorldMixin.java @@ -0,0 +1,20 @@ +package de.hysky.skyblocker.mixin; + +import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.Entity; +import net.minecraft.entity.ItemEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +@Mixin(ClientWorld.class) +public class ClientWorldMixin { + @ModifyVariable(method = "removeEntity", at = @At(value = "LOAD", ordinal = 1)) + private Entity skyblocker$onEntityRemoved(Entity entity) { + if (entity instanceof ItemEntity itemEntity) { + DungeonManager.onItemPickup(itemEntity); + } + return entity; + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java index a207ddc7..a84e6e2b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java @@ -616,7 +616,7 @@ public class DungeonManager { String message = text.getString(); - if (overlay && isCurrentRoomMatched()) { + if (isCurrentRoomMatched()) { currentRoom.onChatMessage(message); } @@ -666,7 +666,7 @@ public class DungeonManager { @SuppressWarnings("JavadocReference") private static ActionResult onUseBlock(World world, BlockHitResult hitResult) { if (isCurrentRoomMatched()) { - currentRoom.onUseBlock(world, hitResult); + currentRoom.onUseBlock(world, hitResult.getBlockPos()); } return ActionResult.PASS; } @@ -677,16 +677,10 @@ public class DungeonManager { * If the collector is the player, {@link #currentRoom} is used as an optimization. */ @SuppressWarnings("JavadocReference") - public static void onItemPickup(ItemEntity itemEntity, LivingEntity collector, boolean isPlayer) { - if (isPlayer) { - if (isCurrentRoomMatched()) { - currentRoom.onItemPickup(itemEntity, collector); - } - } else { - Room room = getRoomAtPhysical(collector.getPos()); - if (isRoomMatched(room)) { - room.onItemPickup(itemEntity, collector); - } + public static void onItemPickup(ItemEntity itemEntity) { + Room room = getRoomAtPhysical(itemEntity.getPos()); + if (isRoomMatched(room)) { + room.onItemPickup(itemEntity); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java index a1bafc20..5b20b48f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java @@ -29,12 +29,10 @@ import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.world.ClientWorld; import net.minecraft.command.argument.EnumArgumentType; import net.minecraft.entity.ItemEntity; -import net.minecraft.entity.LivingEntity; import net.minecraft.entity.mob.AmbientEntity; import net.minecraft.registry.Registries; import net.minecraft.text.Text; import net.minecraft.util.StringIdentifiable; -import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import net.minecraft.util.math.Vec3d; @@ -54,6 +52,7 @@ import java.util.regex.Pattern; public class Room implements Tickable, Renderable { private static final Pattern SECRET_INDEX = Pattern.compile("^(\\d+)"); private static final Pattern SECRETS = Pattern.compile("ยง7(\\d{1,2})/(\\d{1,2}) Secrets"); + private static final String LOCKED_CHEST = "That chest is locked!"; private static final Vec3d DOOR_SIZE = new Vec3d(3, 4, 3); protected static final float[] RED_COLOR_COMPONENTS = {1, 0, 0}; protected static final float[] GREEN_COLOR_COMPONENTS = {0, 1, 0}; @@ -99,6 +98,8 @@ public class Room implements Tickable, Renderable { protected List<Tickable> tickables = new ArrayList<>(); protected List<Renderable> renderables = new ArrayList<>(); + private BlockPos lastChestSecret; + private long lastChestSecretTime; /** * Stores the next room in the dungeon. Currently only used if the next room is the fairy room. */ @@ -207,7 +208,7 @@ public class Room implements Tickable, Renderable { SecretWaypoint.Category category = SecretWaypoint.Category.CategoryArgumentType.getCategory(context, "category"); Text waypointName = context.getArgument("name", Text.class); addCustomWaypoint(secretIndex, category, waypointName, pos); - context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.dungeons.secrets.customWaypointAdded", pos.getX(), pos.getY(), pos.getZ(), name, secretIndex, category, waypointName))); + context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.stringifiedTranslatable("skyblocker.dungeons.secrets.customWaypointAdded", pos.getX(), pos.getY(), pos.getZ(), name, secretIndex, category, waypointName))); } /** @@ -241,7 +242,7 @@ public class Room implements Tickable, Renderable { protected void removeCustomWaypoint(CommandContext<FabricClientCommandSource> context, BlockPos pos) { SecretWaypoint waypoint = removeCustomWaypoint(pos); if (waypoint != null) { - context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.dungeons.secrets.customWaypointRemoved", pos.getX(), pos.getY(), pos.getZ(), name, waypoint.secretIndex, waypoint.category, waypoint.name))); + context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.stringifiedTranslatable("skyblocker.dungeons.secrets.customWaypointRemoved", pos.getX(), pos.getY(), pos.getZ(), name, waypoint.secretIndex, waypoint.category, waypoint.name))); } else { context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.dungeons.secrets.customWaypointNotFound", pos.getX(), pos.getY(), pos.getZ(), name))); } @@ -549,11 +550,14 @@ public class Room implements Tickable, Renderable { } /** - * Sets all secrets as found if {@link #isAllSecretsFound(String)}. + * Sets all secrets as found if {@link #isAllSecretsFound(String)} and sets {@link #lastChestSecret} as missing if message equals {@link #LOCKED_CHEST}. */ protected void onChatMessage(String message) { if (isAllSecretsFound(message)) { secretWaypoints.values().forEach(SecretWaypoint::setFound); + } else if (LOCKED_CHEST.equals(message) && lastChestSecretTime + 1000 > System.currentTimeMillis() && lastChestSecret != null) { + secretWaypoints.column(lastChestSecret).values().stream().filter(SecretWaypoint::needsInteraction).findAny() + .ifPresent(secretWaypoint -> markSecretsAndLogInfo(secretWaypoint, false, "[Skyblocker Dungeon Secrets] Detected locked chest interaction, setting secret #{} as missing", secretWaypoint.secretIndex)); } } @@ -572,58 +576,72 @@ public class Room implements Tickable, Renderable { } /** - * Marks the secret at the interaction position as found when the player interacts with a chest or a player head, - * if there is a secret at the interaction position. + * Marks the secret at the interaction position as found when the player interacts with a chest, player head, or lever + * if there is a secret at the interaction position and saves the position to {@link #lastChestSecret} if the block is a chest. * - * @param world the world to get the block from - * @param hitResult the block being interacted with - * @see #onSecretFound(SecretWaypoint, String, Object...) + * @param world the world to get the block from + * @param pos the position of the block being interacted with + * @see #markSecretsFoundAndLogInfo(SecretWaypoint, String, Object...) */ - protected void onUseBlock(World world, BlockHitResult hitResult) { - BlockState state = world.getBlockState(hitResult.getBlockPos()); - if (state.isOf(Blocks.CHEST) || state.isOf(Blocks.PLAYER_HEAD) || state.isOf(Blocks.PLAYER_WALL_HEAD)) { - secretWaypoints.column(hitResult.getBlockPos()).values().stream().filter(SecretWaypoint::needsInteraction).findAny() - .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker Dungeon Secrets] Detected {} interaction, setting secret #{} as found", secretWaypoint.category, secretWaypoint.secretIndex)); + protected void onUseBlock(World world, BlockPos pos) { + BlockState state = world.getBlockState(pos); + if ((state.isOf(Blocks.CHEST) || state.isOf(Blocks.TRAPPED_CHEST)) && lastChestSecretTime + 1000 < System.currentTimeMillis() || state.isOf(Blocks.PLAYER_HEAD) || state.isOf(Blocks.PLAYER_WALL_HEAD)) { + secretWaypoints.column(pos).values().stream().filter(SecretWaypoint::needsInteraction).findAny() + .ifPresent(secretWaypoint -> markSecretsFoundAndLogInfo(secretWaypoint, "[Skyblocker Dungeon Secrets] Detected {} interaction, setting secret #{} as found", secretWaypoint.category, secretWaypoint.secretIndex)); + if (state.isOf(Blocks.CHEST) || state.isOf(Blocks.TRAPPED_CHEST)) { + lastChestSecret = pos; + lastChestSecretTime = System.currentTimeMillis(); + } } else if (state.isOf(Blocks.LEVER)) { - secretWaypoints.column(hitResult.getBlockPos()).values().stream().filter(SecretWaypoint::isLever).forEach(SecretWaypoint::setFound); + secretWaypoints.column(pos).values().stream().filter(SecretWaypoint::isLever).forEach(SecretWaypoint::setFound); } } /** - * Marks the closest secret that requires item pickup no greater than 6 blocks away as found when the player picks up a secret item. + * Marks the closest secret that requires item pickup no greater than 6 blocks away as found when a secret item is removed from the world. * * @param itemEntity the item entity being picked up - * @param collector the collector of the item - * @see #onSecretFound(SecretWaypoint, String, Object...) + * @see #markSecretsFoundAndLogInfo(SecretWaypoint, String, Object...) */ - protected void onItemPickup(ItemEntity itemEntity, LivingEntity collector) { + protected void onItemPickup(ItemEntity itemEntity) { if (SecretWaypoint.SECRET_ITEMS.stream().noneMatch(itemEntity.getStack().getName().getString()::contains)) { return; } - secretWaypoints.values().stream().filter(SecretWaypoint::needsItemPickup).min(Comparator.comparingDouble(SecretWaypoint.getSquaredDistanceToFunction(collector))).filter(SecretWaypoint.getRangePredicate(collector)) - .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker Dungeon Secrets] Detected {} picked up a {} from a {} secret, setting secret #{} as found", collector.getName().getString(), itemEntity.getName().getString(), secretWaypoint.category, secretWaypoint.secretIndex)); + secretWaypoints.values().stream().filter(SecretWaypoint::needsItemPickup).min(Comparator.comparingDouble(SecretWaypoint.getSquaredDistanceToFunction(itemEntity))).filter(SecretWaypoint.getRangePredicate(itemEntity)) + .ifPresent(secretWaypoint -> markSecretsFoundAndLogInfo(secretWaypoint, "[Skyblocker Dungeon Secrets] Detected item {} removed from a {} secret, setting secret #{} as found", itemEntity.getName().getString(), secretWaypoint.category, secretWaypoint.secretIndex)); } /** * Marks the closest bat secret as found when a bat is killed. * * @param bat the bat being killed - * @see #onSecretFound(SecretWaypoint, String, Object...) + * @see #markSecretsFoundAndLogInfo(SecretWaypoint, String, Object...) */ protected void onBatRemoved(AmbientEntity bat) { secretWaypoints.values().stream().filter(SecretWaypoint::isBat).min(Comparator.comparingDouble(SecretWaypoint.getSquaredDistanceToFunction(bat))) - .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker Dungeon Secrets] Detected {} killed for a {} secret, setting secret #{} as found", bat.getName().getString(), secretWaypoint.category, secretWaypoint.secretIndex)); + .ifPresent(secretWaypoint -> markSecretsFoundAndLogInfo(secretWaypoint, "[Skyblocker Dungeon Secrets] Detected {} killed for a {} secret, setting secret #{} as found", bat.getName().getString(), secretWaypoint.category, secretWaypoint.secretIndex)); } /** - * Marks all secret waypoints with the same index as the given {@link SecretWaypoint} as found. + * Marks all secret waypoints with the same index as the given {@link SecretWaypoint} as found and logs the given message. * * @param secretWaypoint the secret waypoint to read the index from. * @param msg the message to log * @param args the args for the {@link org.slf4j.Logger#info(String, Object...) Logger#info(String, Object...)} call */ - private void onSecretFound(SecretWaypoint secretWaypoint, String msg, Object... args) { - secretWaypoints.row(secretWaypoint.secretIndex).values().forEach(SecretWaypoint::setFound); + private void markSecretsFoundAndLogInfo(SecretWaypoint secretWaypoint, String msg, Object... args) { + markSecretsAndLogInfo(secretWaypoint, true, msg, args); + } + + /** + * Marks all secret waypoints with the same index as the given {@link SecretWaypoint} as found or missing and logs the given message. + * @param secretWaypoint the secret waypoint to read the index from. + * @param found whether to mark the secret as found or missing + * @param msg the message to log + * @param args the args for the {@link org.slf4j.Logger#info(String, Object...) Logger#info(String, Object...)} call + */ + private void markSecretsAndLogInfo(SecretWaypoint secretWaypoint, boolean found, String msg, Object... args) { + markSecrets(secretWaypoint.secretIndex, found); DungeonManager.LOGGER.info(msg, args); } diff --git a/src/main/resources/assets/skyblocker/dungeons/secretlocations.json b/src/main/resources/assets/skyblocker/dungeons/secretlocations.json index 0f22f597..760e72d9 100644 --- a/src/main/resources/assets/skyblocker/dungeons/secretlocations.json +++ b/src/main/resources/assets/skyblocker/dungeons/secretlocations.json @@ -4730,7 +4730,7 @@ "z":15 }, { - "secretName":"2 - Stonk", + "secretName":"1 - Stonk", "category":"stonk", "x":26, "y":112, diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json index fd7364ce..c996c58d 100644 --- a/src/main/resources/skyblocker.mixins.json +++ b/src/main/resources/skyblocker.mixins.json @@ -9,6 +9,7 @@ "BatEntityMixin", "ClientPlayerEntityMixin", "ClientPlayNetworkHandlerMixin", + "ClientWorldMixin", "DataTrackerMixin", "DrawContextMixin", "DyeableItemMixin", |