From f63c42e27f6ac014ed0ccb4745101b344e6cca6e Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Fri, 22 Dec 2023 18:06:28 +0800 Subject: [PATCH 01/15] Add entity list config `entity_tracker_tweak_list` --- gradle.properties | 2 +- .../potteckit/config/Configs.java | 17 +++++++++ .../config/option/EntityListConfig.java | 36 +++++++++++++++++++ .../potteckit/gui/EntityListConfigWidget.java | 36 +++++++++++++++++++ .../potteckit/gui/EntityWidget.java | 22 ++++++++++++ .../potteckit/util/Reference.java | 2 +- .../assets/potteckit/lang/en_us.lang | 3 ++ 7 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 src/main/java/io/github/rainyaphthyl/potteckit/config/option/EntityListConfig.java create mode 100644 src/main/java/io/github/rainyaphthyl/potteckit/gui/EntityListConfigWidget.java create mode 100644 src/main/java/io/github/rainyaphthyl/potteckit/gui/EntityWidget.java diff --git a/gradle.properties b/gradle.properties index 87445b9..d4cf9e9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ modId=potato_tech_kit modName=Potato Tech Kit # lowercase, without hyphens modPureName=potteckit -modVersion=0.2.2 +modVersion=undefined-post-0.2.2 malilibVersion=0.54.0 diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java b/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java index f5011d6..6ec4928 100644 --- a/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java +++ b/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java @@ -3,23 +3,30 @@ import com.google.common.collect.ImmutableList; import fi.dy.masa.malilib.config.JsonModConfig; import fi.dy.masa.malilib.config.option.*; +import fi.dy.masa.malilib.config.option.list.BlackWhiteListConfig; import fi.dy.masa.malilib.config.option.list.BlockListConfig; import fi.dy.masa.malilib.config.option.list.EquipmentSlotListConfig; import fi.dy.masa.malilib.config.option.list.ItemListConfig; +import fi.dy.masa.malilib.config.value.BlackWhiteList; import fi.dy.masa.malilib.input.KeyBindSettings; import fi.dy.masa.malilib.registry.Registry; +import fi.dy.masa.malilib.util.restriction.UsageRestriction; import io.github.rainyaphthyl.potteckit.config.annotation.Config; import io.github.rainyaphthyl.potteckit.config.annotation.Domain; import io.github.rainyaphthyl.potteckit.config.annotation.Type; +import io.github.rainyaphthyl.potteckit.config.option.EntityListConfig; import io.github.rainyaphthyl.potteckit.config.option.EnumRealmStatus; import io.github.rainyaphthyl.potteckit.config.option.InvIntegerConfig; import io.github.rainyaphthyl.potteckit.config.option.multipart.ChunkFilterListConfig; import io.github.rainyaphthyl.potteckit.entities.Renderers; import io.github.rainyaphthyl.potteckit.gui.ChunkFilterListConfigWidget; +import io.github.rainyaphthyl.potteckit.gui.EntityListConfigWidget; import io.github.rainyaphthyl.potteckit.gui.GuiConfigScreen; import io.github.rainyaphthyl.potteckit.gui.InvIntegerConfigWidget; import io.github.rainyaphthyl.potteckit.input.PotteckitHotkeyProvider; import io.github.rainyaphthyl.potteckit.util.Reference; +import net.minecraft.entity.Entity; +import net.minecraft.entity.passive.EntitySquid; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.inventory.EntityEquipmentSlot; @@ -100,6 +107,15 @@ public class Configs { public static final BooleanAndDoubleConfig explosionPacketRange = new BooleanAndDoubleConfig("explosion_packet_range", false, 64.0, 0.0, 1024.0, "explosion_packet_range"); @Config(types = Type.NUMBER, domains = Domain.TWEAK, serverSide = true) public static final BooleanAndIntConfig entityTrackerDistance = new BooleanAndIntConfig("entity_tracker_distance", false, 8, 0, 64, "entity_tracker_distance"); + @Config(types = Type.LIST, domains = Domain.TWEAK, serverSide = true) + public static final BlackWhiteListConfig> entityTrackerTweakList = new BlackWhiteListConfig<>( + "entity_tracker_tweak_list", + BlackWhiteList.of( + UsageRestriction.ListType.BLACKLIST, + new EntityListConfig("malilib.label.list_type.blacklist", ImmutableList.of(EntitySquid.class)), + new EntityListConfig("malilib.label.list_type.whitelist", ImmutableList.of()) + ), "entity_tracker_tweak_list", "entity_tracker_tweak_list" + ); @Config(types = Type.TOGGLE, domains = Domain.YEET, serverSide = true) public static final HotkeyedBooleanConfig yeetItemAntiSpam = new HotkeyedBooleanConfig("yeet_item_anti_spam", false, "", "yeet_item_anti_spam", "yeet_item_anti_spam"); @Config(types = Type.TOGGLE, domains = Domain.YEET, serverSide = true) @@ -118,6 +134,7 @@ public static void registerOnInit() { Registry.CONFIG_TAB.registerConfigTabProvider(Reference.MOD_INFO, GuiConfigScreen::getConfigTabs); Registry.CONFIG_WIDGET.registerConfigWidgetFactory(InvIntegerConfig.class, InvIntegerConfigWidget::new); Registry.CONFIG_WIDGET.registerConfigWidgetFactory(ChunkFilterListConfig.class, ChunkFilterListConfigWidget::new); + Registry.CONFIG_WIDGET.registerConfigWidgetFactory(EntityListConfig.class, EntityListConfigWidget::new); Registry.HOTKEY_MANAGER.registerHotkeyProvider(new PotteckitHotkeyProvider()); Actions.init(); Callbacks.init(); diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/config/option/EntityListConfig.java b/src/main/java/io/github/rainyaphthyl/potteckit/config/option/EntityListConfig.java new file mode 100644 index 0000000..88edba2 --- /dev/null +++ b/src/main/java/io/github/rainyaphthyl/potteckit/config/option/EntityListConfig.java @@ -0,0 +1,36 @@ +package io.github.rainyaphthyl.potteckit.config.option; + +import com.google.common.collect.ImmutableList; +import fi.dy.masa.malilib.config.option.list.ValueListConfig; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.util.ResourceLocation; + +import java.util.function.Function; + +public class EntityListConfig extends ValueListConfig> { + public static final Function, String> TO_STRING_CONVERTER = eClass -> { + ResourceLocation key = EntityList.getKey(eClass); + return key == null ? null : key.toString(); + }; + public static final Function> FROM_STRING_CONVERTER = EntityList::getClassFromName; + + public EntityListConfig(String name, ImmutableList> defaultValues) { + super(name, defaultValues, TO_STRING_CONVERTER, FROM_STRING_CONVERTER); + } + + public EntityListConfig(String name, ImmutableList> defaultValues, String commentTranslationKey, Object... commentArgs) { + super(name, defaultValues, TO_STRING_CONVERTER, FROM_STRING_CONVERTER, commentTranslationKey, commentArgs); + } + + public EntityListConfig(String name, ImmutableList> defaultValues, Function, String> toStringConverter, Function> fromStringConverter) { + super(name, defaultValues, toStringConverter, fromStringConverter); + } + + @Override + public EntityListConfig copy() { + EntityListConfig config = new EntityListConfig(name, defaultValue, toStringConverter, fromStringConverter); + config.copyValuesFrom(this); + return config; + } +} diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/gui/EntityListConfigWidget.java b/src/main/java/io/github/rainyaphthyl/potteckit/gui/EntityListConfigWidget.java new file mode 100644 index 0000000..a0ec88c --- /dev/null +++ b/src/main/java/io/github/rainyaphthyl/potteckit/gui/EntityListConfigWidget.java @@ -0,0 +1,36 @@ +package io.github.rainyaphthyl.potteckit.gui; + +import com.google.common.collect.ImmutableList; +import fi.dy.masa.malilib.gui.config.ConfigWidgetContext; +import fi.dy.masa.malilib.gui.widget.button.BaseValueListEditButton; +import fi.dy.masa.malilib.gui.widget.button.GenericButton; +import fi.dy.masa.malilib.gui.widget.list.entry.DataListEntryWidgetData; +import fi.dy.masa.malilib.gui.widget.list.entry.config.list.BaseValueListConfigWidget; +import fi.dy.masa.malilib.util.StringUtils; +import io.github.rainyaphthyl.potteckit.config.option.EntityListConfig; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.passive.EntityBat; + +public class EntityListConfigWidget extends BaseValueListConfigWidget, EntityListConfig> { + public EntityListConfigWidget(EntityListConfig config, DataListEntryWidgetData constructData, ConfigWidgetContext ctx) { + super(config, constructData, ctx); + } + + @Override + protected GenericButton createButton(int width, int height, EntityListConfig config, ConfigWidgetContext ctx) { + String title = StringUtils.translate("potteckit.title.screen.item_list_edit", this.config.getDisplayName()); + return new BaseValueListEditButton<>(width, height, config, this::updateWidgetState, + () -> EntityBat.class, + () -> { + ImmutableList.Builder> builder = ImmutableList.builder(); + for (Class eClass : EntityList.REGISTRY) { + builder.add(eClass); + } + return builder.build(); + }, + eClass -> String.valueOf(EntityList.getKey(eClass)), + null, title + ); + } +} diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/gui/EntityWidget.java b/src/main/java/io/github/rainyaphthyl/potteckit/gui/EntityWidget.java new file mode 100644 index 0000000..a68265a --- /dev/null +++ b/src/main/java/io/github/rainyaphthyl/potteckit/gui/EntityWidget.java @@ -0,0 +1,22 @@ +package io.github.rainyaphthyl.potteckit.gui; + +import fi.dy.masa.malilib.gui.util.ScreenContext; +import fi.dy.masa.malilib.gui.widget.BaseModelWidget; +import net.minecraft.entity.Entity; + +public class EntityWidget extends BaseModelWidget { + protected Class entityClass; + + public EntityWidget(Class entityClass) { + this(16, entityClass); + } + + public EntityWidget(int dimensions, Class entityClass) { + super(dimensions); + this.entityClass = entityClass; + } + + @Override + protected void renderModel(int x, int y, float z, float scale, ScreenContext ctx) { + } +} diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/util/Reference.java b/src/main/java/io/github/rainyaphthyl/potteckit/util/Reference.java index 86b0a6b..ecee81a 100644 --- a/src/main/java/io/github/rainyaphthyl/potteckit/util/Reference.java +++ b/src/main/java/io/github/rainyaphthyl/potteckit/util/Reference.java @@ -6,7 +6,7 @@ import org.apache.logging.log4j.Logger; public class Reference { - public static final String VERSION = "0.2.2"; + public static final String VERSION = "undefined-post-0.2.2"; public static final ModVersion versionObj = ModVersion.getVersion(VERSION); public static final String NAME = "PotatoTechKit"; public static final String SHORT_NAME = "potteckit"; diff --git a/src/main/resources/assets/potteckit/lang/en_us.lang b/src/main/resources/assets/potteckit/lang/en_us.lang index ae6bb5b..1178630 100644 --- a/src/main/resources/assets/potteckit/lang/en_us.lang +++ b/src/main/resources/assets/potteckit/lang/en_us.lang @@ -1,4 +1,5 @@ potteckit.title.configs=Potteckit %s - Configs +potteckit.title.screen.entity_list_edit=Edit Entity List §e%s§r potteckit.config.tab.generic=Generic potteckit.config.tab.meter=Meters @@ -95,6 +96,8 @@ potteckit.config.name.explosion_packet_range=§6Explosion Packet Range§r potteckit.config.comment.explosion_packet_range=§6(Server-side Modification)§r\nThe maximum horizontal chebyshev distance (in chunks) for the server to sync entities information to the client. potteckit.config.name.entity_tracker_distance=§6Entity Tracker Distance§r potteckit.config.comment.entity_tracker_distance=§6(Server-side Modification)§r\nSet the range where player will receive an explosion packet when an explosion happens. +potteckit.config.name.entity_tracker_tweak_list=§6Entity Tracker Tweak List§r +potteckit.config.comment.entity_tracker_tweak_list=§6(Server-side Modification)§r\n.The filter of entity types affected by "§6Entity Tracker Distance§r". potteckit.config.name.yeet_item_anti_spam=§6Disable Item Drop Antispam§r potteckit.config.comment.yeet_item_anti_spam=§6(Server-side Modification)§r\nDisables spamming checks on players about creative item drop cool down. potteckit.config.name.yeet_chat_anti_spam=§6Disable Chat Antispam§r From 6660961c51611c2fd26d1744d37df93080af4a7c Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Fri, 22 Dec 2023 23:14:27 +0800 Subject: [PATCH 02/15] Implement `entity_tracker_tweak_list` --- .../mixin/sync/MixinEntityTrackerEntry.java | 23 ++++++++++++++++++- .../assets/potteckit/lang/en_us.lang | 2 +- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/sync/MixinEntityTrackerEntry.java b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/sync/MixinEntityTrackerEntry.java index df85800..2436fd8 100644 --- a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/sync/MixinEntityTrackerEntry.java +++ b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/sync/MixinEntityTrackerEntry.java @@ -1,6 +1,11 @@ package io.github.rainyaphthyl.potteckit.mixin.sync; +import com.google.common.collect.ImmutableList; +import fi.dy.masa.malilib.config.option.list.ValueListConfig; +import fi.dy.masa.malilib.config.value.BlackWhiteList; +import fi.dy.masa.malilib.util.restriction.UsageRestriction; import io.github.rainyaphthyl.potteckit.config.Configs; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityTrackerEntry; import org.spongepowered.asm.lib.Opcodes; import org.spongepowered.asm.mixin.Final; @@ -18,7 +23,23 @@ public abstract class MixinEntityTrackerEntry { @Redirect(method = "isVisibleTo", at = @At(value = "FIELD", opcode = Opcodes.GETFIELD, target = "Lnet/minecraft/entity/EntityTrackerEntry;range:I")) public int onCheckTrackerDistance(EntityTrackerEntry instance) { if (Configs.entityTrackerDistance.getBooleanValue() && Configs.enablePotteckit.getBooleanValue()) { - return Configs.entityTrackerDistance.getIntegerValue() * 16; + BlackWhiteList> filter = Configs.entityTrackerTweakList.getValue(); + UsageRestriction.ListType listType = filter.getListType(); + ValueListConfig> activeList = filter.getActiveList(); + if (activeList != null) { + Class entityType = instance.getTrackedEntity().getClass(); + ImmutableList> list = activeList.getValue(); + if (listType == UsageRestriction.ListType.BLACKLIST) { + if (list.contains(entityType)) { + return range; + } + } else if (listType == UsageRestriction.ListType.WHITELIST) { + if (!list.contains(entityType)) { + return range; + } + } + } + return Configs.entityTrackerDistance.getIntegerValue() << 4; } else { return range; } diff --git a/src/main/resources/assets/potteckit/lang/en_us.lang b/src/main/resources/assets/potteckit/lang/en_us.lang index 1178630..438bc88 100644 --- a/src/main/resources/assets/potteckit/lang/en_us.lang +++ b/src/main/resources/assets/potteckit/lang/en_us.lang @@ -97,7 +97,7 @@ potteckit.config.comment.explosion_packet_range=§6(Server-side Modification)§r potteckit.config.name.entity_tracker_distance=§6Entity Tracker Distance§r potteckit.config.comment.entity_tracker_distance=§6(Server-side Modification)§r\nSet the range where player will receive an explosion packet when an explosion happens. potteckit.config.name.entity_tracker_tweak_list=§6Entity Tracker Tweak List§r -potteckit.config.comment.entity_tracker_tweak_list=§6(Server-side Modification)§r\n.The filter of entity types affected by "§6Entity Tracker Distance§r". +potteckit.config.comment.entity_tracker_tweak_list=§6(Server-side Modification)§r\nThe filter of entity types affected by "§6Entity Tracker Distance§r". potteckit.config.name.yeet_item_anti_spam=§6Disable Item Drop Antispam§r potteckit.config.comment.yeet_item_anti_spam=§6(Server-side Modification)§r\nDisables spamming checks on players about creative item drop cool down. potteckit.config.name.yeet_chat_anti_spam=§6Disable Chat Antispam§r From fc730bd534a0d39595dc68d8ad694bec1d47eb29 Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Sun, 22 Sep 2024 15:20:23 +0800 Subject: [PATCH 03/15] Todo list of a lag fix? --- ChangeLog.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index acfd952..9bc2100 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -48,3 +48,8 @@ Configs of "Creative Invulnerable Crystal", Antispam, Packets, and Trackers, fro ## Modified Features ## Code Changes + +## To-do List + +1. Fix the bug that + `root.tick.level.blocks.getChunk.checkedPosition` causes huge lag(?) when elytra-flying over the nether. From 1483b6756baa63cf25632cf44586643124aab81d Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Tue, 24 Sep 2024 23:22:18 +0800 Subject: [PATCH 04/15] Add config "Disable Travel Light Check" --- .../java/io/github/rainyaphthyl/potteckit/config/Configs.java | 2 ++ src/main/resources/assets/potteckit/lang/en_us.lang | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java b/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java index 6ec4928..824a1cf 100644 --- a/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java +++ b/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java @@ -126,6 +126,8 @@ public class Configs { public static final EquipmentSlotListConfig protectCreativeSlotList = new EquipmentSlotListConfig("protect_creative_slot_list", ImmutableList.of(EntityEquipmentSlot.CHEST, EntityEquipmentSlot.FEET)); @Config(types = Type.TOGGLE, domains = Domain.YEET) public static final BooleanAndIntConfig dynamicFPS = new BooleanAndIntConfig("dynamic_fps", false, 5, 1, 20, "dynamic_fps"); + @Config(types = Type.TOGGLE, domains = Domain.YEET) + public static final HotkeyedBooleanConfig yeetTravelLightCheck = new HotkeyedBooleanConfig("yeet_travel_light_check", false, "", "yeet_travel_light_check", "yeet_travel_light_check"); public static void registerOnInit() { JsonModConfig jsonModConfig = new JsonModConfig(Reference.MOD_INFO, Reference.CONFIG_VERSION, ConfigHandler.optionCategoryList); diff --git a/src/main/resources/assets/potteckit/lang/en_us.lang b/src/main/resources/assets/potteckit/lang/en_us.lang index 438bc88..7718d9b 100644 --- a/src/main/resources/assets/potteckit/lang/en_us.lang +++ b/src/main/resources/assets/potteckit/lang/en_us.lang @@ -102,6 +102,8 @@ potteckit.config.name.yeet_item_anti_spam=§6Disable Item Drop Antispam§r potteckit.config.comment.yeet_item_anti_spam=§6(Server-side Modification)§r\nDisables spamming checks on players about creative item drop cool down. potteckit.config.name.yeet_chat_anti_spam=§6Disable Chat Antispam§r potteckit.config.comment.yeet_chat_anti_spam=§6(Server-side Modification)§r\nDisables spamming checks on players about chat message cool down. +potteckit.config.name.yeet_travel_light_check=Disable Travel Light Check +potteckit.config.comment.yeet_travel_light_check=Disables the chunk light check that causes huge client-side lag spikes when the player is traveling fast. (e.g. elytra-gliding above the nether) potteckit.config.name.protect_creative_slots=Protect Creative Slots potteckit.config.comment.protect_creative_slots=Protects the items at the given slots from being destroyed when shift-clicking the "Destroy Item" button. E.g. you may not want to delete your elytra. From c227473a534553ee98d60bdb8b39b427000de2a6 Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Wed, 25 Sep 2024 19:01:26 +0800 Subject: [PATCH 05/15] Implement config "Disable Travel Light Check" --- .../potteckit/mixin/render/MixinWorld.java | 44 +++++++++++++++++++ src/main/resources/mixins.potteckit.json | 1 + 2 files changed, 45 insertions(+) create mode 100644 src/main/java/io/github/rainyaphthyl/potteckit/mixin/render/MixinWorld.java diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/render/MixinWorld.java b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/render/MixinWorld.java new file mode 100644 index 0000000..041b84c --- /dev/null +++ b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/render/MixinWorld.java @@ -0,0 +1,44 @@ +package io.github.rainyaphthyl.potteckit.mixin.render; + +import io.github.rainyaphthyl.potteckit.config.Configs; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.EnumSkyBlock; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(World.class) +public abstract class MixinWorld { + @Shadow + @Final + public boolean isRemote; + + @Inject(method = "checkLightFor", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/profiler/Profiler;startSection(Ljava/lang/String;)V", args = "ldc=checkedPosition < toCheckCount"), cancellable = true) + public void yeetPositionsToCheck(EnumSkyBlock lightType, BlockPos pos, CallbackInfoReturnable cir) { + if (Configs.enablePotteckit.getBooleanValue() && this.isRemote && Configs.yeetTravelLightCheck.getBooleanValue()) { + Entity viewEntity = Minecraft.getMinecraft().getRenderViewEntity(); + if (viewEntity != null && viewEntity.dimension == -1) { + if (viewEntity.motionX * viewEntity.motionX + viewEntity.motionZ * viewEntity.motionZ + viewEntity.motionY * viewEntity.motionY >= 0.3 * 0.3) { + if (cir.isCancellable() && !cir.isCancelled()) { + cir.setReturnValue(true); + } + } else { + Entity ridingEntity = viewEntity.getRidingEntity(); + if (ridingEntity != null) { + if (ridingEntity.motionX * ridingEntity.motionX + ridingEntity.motionZ * ridingEntity.motionZ + ridingEntity.motionY * ridingEntity.motionY >= 0.3 * 0.3) { + if (cir.isCancellable() && !cir.isCancelled()) { + cir.setReturnValue(true); + } + } + } + } + } + } + } +} diff --git a/src/main/resources/mixins.potteckit.json b/src/main/resources/mixins.potteckit.json index 0f8ba19..acff66d 100644 --- a/src/main/resources/mixins.potteckit.json +++ b/src/main/resources/mixins.potteckit.json @@ -35,6 +35,7 @@ "render.MixinEntityRenderer", "render.MixinRenderChunk", "render.MixinRenderGlobal", + "render.MixinWorld", "sync.MixinEntityTrackerEntry", "sync.MixinNetHandlerPlayServer", "sync.MixinWorld", From 7cb616f39da0f51868ba5fd0ba43e23bc477858b Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Fri, 27 Sep 2024 15:01:54 +0800 Subject: [PATCH 06/15] Disable Travel Light Check only if playerSP==viewEntity --- .../potteckit/mixin/render/MixinWorld.java | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/render/MixinWorld.java b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/render/MixinWorld.java index 041b84c..d4729ab 100644 --- a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/render/MixinWorld.java +++ b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/render/MixinWorld.java @@ -9,6 +9,7 @@ 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.CallbackInfoReturnable; @@ -19,24 +20,33 @@ public abstract class MixinWorld { @Final public boolean isRemote; + @Unique + private static boolean potatoTechKit$needClientUpdate(Entity entity) { + boolean flag = false; + if (entity != null && entity.dimension == -1) { + if (entity.motionX * entity.motionX + entity.motionZ * entity.motionZ + entity.motionY * entity.motionY >= 0.3 * 0.3) { + flag = true; + } else { + Entity ridingEntity = entity.getRidingEntity(); + if (ridingEntity != null) { + if (ridingEntity.motionX * ridingEntity.motionX + ridingEntity.motionZ * ridingEntity.motionZ + ridingEntity.motionY * ridingEntity.motionY >= 0.3 * 0.3) { + flag = true; + } + } + } + } + return flag; + } + @Inject(method = "checkLightFor", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/profiler/Profiler;startSection(Ljava/lang/String;)V", args = "ldc=checkedPosition < toCheckCount"), cancellable = true) public void yeetPositionsToCheck(EnumSkyBlock lightType, BlockPos pos, CallbackInfoReturnable cir) { if (Configs.enablePotteckit.getBooleanValue() && this.isRemote && Configs.yeetTravelLightCheck.getBooleanValue()) { - Entity viewEntity = Minecraft.getMinecraft().getRenderViewEntity(); - if (viewEntity != null && viewEntity.dimension == -1) { - if (viewEntity.motionX * viewEntity.motionX + viewEntity.motionZ * viewEntity.motionZ + viewEntity.motionY * viewEntity.motionY >= 0.3 * 0.3) { - if (cir.isCancellable() && !cir.isCancelled()) { - cir.setReturnValue(true); - } - } else { - Entity ridingEntity = viewEntity.getRidingEntity(); - if (ridingEntity != null) { - if (ridingEntity.motionX * ridingEntity.motionX + ridingEntity.motionZ * ridingEntity.motionZ + ridingEntity.motionY * ridingEntity.motionY >= 0.3 * 0.3) { - if (cir.isCancellable() && !cir.isCancelled()) { - cir.setReturnValue(true); - } - } - } + Minecraft client = Minecraft.getMinecraft(); + Entity viewEntity = client.getRenderViewEntity(); + if (client.player == viewEntity) { + boolean flag = potatoTechKit$needClientUpdate(viewEntity); + if (flag && cir.isCancellable() && !cir.isCancelled()) { + cir.setReturnValue(true); } } } From 931de82a904b0f0291e862db9ff5c66389510300 Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Fri, 27 Sep 2024 22:41:48 +0800 Subject: [PATCH 07/15] Todo list to fix MC-88179 --- ChangeLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.md b/ChangeLog.md index 9bc2100..1a1c4a7 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -53,3 +53,4 @@ Configs of "Creative Invulnerable Crystal", Antispam, Packets, and Trackers, fro 1. Fix the bug that `root.tick.level.blocks.getChunk.checkedPosition` causes huge lag(?) when elytra-flying over the nether. +2. Fix [MC-88179](https://bugs.mojang.com/browse/MC-88179): Armor bar disappears after changing dimension until GUI update. From edf428c37eb542a77311ab4ac638fb2434e2d1e2 Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Wed, 30 Oct 2024 23:18:25 +0800 Subject: [PATCH 08/15] New config tab: swap_elytra_chestplate --- .../java/io/github/rainyaphthyl/potteckit/config/Configs.java | 2 ++ src/main/resources/assets/potteckit/lang/en_us.lang | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java b/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java index 824a1cf..4558f8e 100644 --- a/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java +++ b/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java @@ -128,6 +128,8 @@ public class Configs { public static final BooleanAndIntConfig dynamicFPS = new BooleanAndIntConfig("dynamic_fps", false, 5, 1, 20, "dynamic_fps"); @Config(types = Type.TOGGLE, domains = Domain.YEET) public static final HotkeyedBooleanConfig yeetTravelLightCheck = new HotkeyedBooleanConfig("yeet_travel_light_check", false, "", "yeet_travel_light_check", "yeet_travel_light_check"); + @Config(types = Type.TOGGLE, domains = Domain.TWEAK) + public static final HotkeyedBooleanConfig swapElytraChestplate = new HotkeyedBooleanConfig("swap_elytra_chestplate", false, "", "swap_elytra_chestplate", "swap_elytra_chestplate"); public static void registerOnInit() { JsonModConfig jsonModConfig = new JsonModConfig(Reference.MOD_INFO, Reference.CONFIG_VERSION, ConfigHandler.optionCategoryList); diff --git a/src/main/resources/assets/potteckit/lang/en_us.lang b/src/main/resources/assets/potteckit/lang/en_us.lang index 7718d9b..19d4999 100644 --- a/src/main/resources/assets/potteckit/lang/en_us.lang +++ b/src/main/resources/assets/potteckit/lang/en_us.lang @@ -109,3 +109,6 @@ potteckit.config.name.protect_creative_slots=Protect Creative Slots potteckit.config.comment.protect_creative_slots=Protects the items at the given slots from being destroyed when shift-clicking the "Destroy Item" button. E.g. you may not want to delete your elytra. potteckit.config.name.protect_creative_slot_list=Protect Creative Slot List potteckit.config.comment.protect_creative_slot_list=The list of items to be protected by the config "Protect Creative Slots". + +potteckit.config.name.swap_elytra_chestplate=Swap Elytra Chestplate +potteckit.config.comment.swap_elytra_chestplate=Automatically swaps between Elytra and Chestplates when the player is taking off or landing. From 70cce68e8f9339284b367d417dc395588189f75e Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Fri, 1 Nov 2024 01:34:45 +0800 Subject: [PATCH 09/15] Elytra Auto Deploy --- .../mixin/inventory/MixinEntityPlayerSP.java | 86 +++++++++++++++++++ src/main/resources/mixins.potteckit.json | 1 + 2 files changed, 87 insertions(+) create mode 100644 src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java new file mode 100644 index 0000000..b380212 --- /dev/null +++ b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java @@ -0,0 +1,86 @@ +package io.github.rainyaphthyl.potteckit.mixin.inventory; + +import com.mojang.authlib.GameProfile; +import fi.dy.masa.malilib.util.inventory.InventoryUtils; +import io.github.rainyaphthyl.potteckit.config.Configs; +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.init.Enchantments; +import net.minecraft.inventory.ClickType; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemElytra; +import net.minecraft.item.ItemStack; +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.CallbackInfo; + +@Mixin(EntityPlayerSP.class) +public abstract class MixinEntityPlayerSP extends AbstractClientPlayer { + @Unique + private ItemStack potatoTechKit$cachedChestStack = ItemStack.EMPTY; + + public MixinEntityPlayerSP(World worldIn, GameProfile playerProfile) { + super(worldIn, playerProfile); + } + + @Inject(method = "onLivingUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;getItemStackFromSlot(Lnet/minecraft/inventory/EntityEquipmentSlot;)Lnet/minecraft/item/ItemStack;")) + public void autoDeployElytra(CallbackInfo ci) { + if (Configs.enablePotteckit.getBooleanValue() && Configs.swapElytraChestplate.getBooleanValue()) { + ItemStack chestStack = getItemStackFromSlot(EntityEquipmentSlot.CHEST); + if (chestStack.getItem() instanceof ItemArmor) { + ItemStack elytraStack = ItemStack.EMPTY; + Slot elytraSlot = null; + int prevDurability = 0; + boolean prevMending = false; + for (int i = -1; i < 36; ++i) { + int id = i == -1 ? 45 : + (i < 9 ? i + 36 : i); + Slot currSlot = inventoryContainer.getSlot(id); + ItemStack currStack = currSlot.getStack(); + if (!currStack.isEmpty() && currStack.getItem() instanceof ItemElytra) { + int level = EnchantmentHelper.getEnchantmentLevel(Enchantments.UNBREAKING, currStack); + int damage = currStack.getItemDamage(); + boolean mending = EnchantmentHelper.getEnchantmentLevel(Enchantments.MENDING, currStack) > 0; + int durability = (currStack.getMaxDamage() - damage) * (level + 1); + // find the first of the best elytra(s): + // best remaining durability: (remaining durability) * (unbreaking grade) + // mending is better + if (elytraStack.isEmpty() + || durability > prevDurability + || durability == prevDurability && !prevMending && mending) { + elytraSlot = currSlot; + elytraStack = currStack; + prevDurability = durability; + prevMending = mending; + } + if (mending && level >= Enchantments.UNBREAKING.getMaxLevel() && damage == 0) { + // the perfect elytra + break; + } + } + } + if (elytraSlot != null && !elytraStack.isEmpty()) { + //swap Elytra & Chestplate + Slot chestSlot = inventoryContainer.getSlot(6); + int slotNumber = elytraSlot.slotNumber; + if (slotNumber >= 36 && slotNumber < 45) { + // hot-bar + InventoryUtils.clickSlot(inventoryContainer, chestSlot, slotNumber - 36, ClickType.SWAP); + } else { + int currentItem = inventory.currentItem; + InventoryUtils.clickSlot(inventoryContainer, elytraSlot, currentItem, ClickType.SWAP); + InventoryUtils.clickSlot(inventoryContainer, chestSlot, currentItem, ClickType.SWAP); + InventoryUtils.clickSlot(inventoryContainer, elytraSlot, currentItem, ClickType.SWAP); + } + potatoTechKit$cachedChestStack = chestStack; + } + } + } + } +} diff --git a/src/main/resources/mixins.potteckit.json b/src/main/resources/mixins.potteckit.json index acff66d..59170f3 100644 --- a/src/main/resources/mixins.potteckit.json +++ b/src/main/resources/mixins.potteckit.json @@ -25,6 +25,7 @@ "gamephase.MixinWorldProvider", "gamephase.MixinWorldProviderEnd", "gamephase.MixinWorldServer", + "inventory.MixinEntityPlayerSP", "inventory.MixinGuiContainerCreative", "meters.MixinEntityPlayerSP", "optifix.MixinPlayerList", From c01add0cbf4eba2fbafd9c9f6069f7d3ef37d56b Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Fri, 1 Nov 2024 03:35:36 +0800 Subject: [PATCH 10/15] Elytra Auto Deploy (reverse) --- .../mixin/inventory/MixinEntityPlayerSP.java | 55 +++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java index b380212..9dc3e99 100644 --- a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java +++ b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java @@ -7,14 +7,17 @@ import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.init.Enchantments; +import net.minecraft.init.Items; import net.minecraft.inventory.ClickType; import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.inventory.Slot; +import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; -import net.minecraft.item.ItemElytra; import net.minecraft.item.ItemStack; +import net.minecraft.network.datasync.DataParameter; import net.minecraft.world.World; 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; @@ -22,6 +25,8 @@ @Mixin(EntityPlayerSP.class) public abstract class MixinEntityPlayerSP extends AbstractClientPlayer { + @Shadow + private boolean wasFallFlying; @Unique private ItemStack potatoTechKit$cachedChestStack = ItemStack.EMPTY; @@ -39,11 +44,10 @@ public void autoDeployElytra(CallbackInfo ci) { int prevDurability = 0; boolean prevMending = false; for (int i = -1; i < 36; ++i) { - int id = i == -1 ? 45 : - (i < 9 ? i + 36 : i); + int id = i == -1 ? 45 : (i < 9 ? i + 36 : i); Slot currSlot = inventoryContainer.getSlot(id); ItemStack currStack = currSlot.getStack(); - if (!currStack.isEmpty() && currStack.getItem() instanceof ItemElytra) { + if (!currStack.isEmpty() && currStack.getItem() == Items.ELYTRA) { int level = EnchantmentHelper.getEnchantmentLevel(Enchantments.UNBREAKING, currStack); int damage = currStack.getItemDamage(); boolean mending = EnchantmentHelper.getEnchantmentLevel(Enchantments.MENDING, currStack) > 0; @@ -83,4 +87,47 @@ public void autoDeployElytra(CallbackInfo ci) { } } } + + @Inject(method = "notifyDataManagerChange", at = @At(value = "RETURN")) + public void autoDeployChestplate(DataParameter key, CallbackInfo ci) { + if (Configs.enablePotteckit.getBooleanValue() && Configs.swapElytraChestplate.getBooleanValue()) { + if (FLAGS.equals(key) && !isElytraFlying() && wasFallFlying) { + // the new data have been refreshed during EntityDataManager.setEntryValue() + ItemStack elytraStack = getItemStackFromSlot(EntityEquipmentSlot.CHEST); + Slot chestSlot = null; + ItemStack chestStack = ItemStack.EMPTY; + if (elytraStack.getItem() == Items.ELYTRA) { + for (int i = -1; i < 36; ++i) { + int id = i == -1 ? 45 : (i < 9 ? i + 36 : i); + Slot currSlot = inventoryContainer.getSlot(id); + ItemStack currStack = currSlot.getStack(); + if (!currStack.isEmpty()) { + Item currItem = currStack.getItem(); + if (currItem instanceof ItemArmor + && ((ItemArmor) currItem).armorType == EntityEquipmentSlot.CHEST + && InventoryUtils.areStacksEqualIgnoreDurability(potatoTechKit$cachedChestStack, currStack, false)) { + chestSlot = currSlot; + chestStack = currStack; + break; + } + } + } + } + if (chestSlot != null && !chestStack.isEmpty()) { + Slot elytraSlot = inventoryContainer.getSlot(6); + int slotNumber = chestSlot.slotNumber; + if (slotNumber >= 36 && slotNumber < 45) { + // hot-bar + InventoryUtils.clickSlot(inventoryContainer, elytraSlot, slotNumber - 36, ClickType.SWAP); + } else { + int currentItem = inventory.currentItem; + InventoryUtils.clickSlot(inventoryContainer, chestSlot, currentItem, ClickType.SWAP); + InventoryUtils.clickSlot(inventoryContainer, elytraSlot, currentItem, ClickType.SWAP); + InventoryUtils.clickSlot(inventoryContainer, chestSlot, currentItem, ClickType.SWAP); + } + potatoTechKit$cachedChestStack = ItemStack.EMPTY; + } + } + } + } } From aa74fb839ecee3300de0f15a1c9ba4297ba67c18 Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Fri, 1 Nov 2024 03:45:34 +0800 Subject: [PATCH 11/15] Add in-game doc of `AutoSwapElytraChestplate` --- .../java/io/github/rainyaphthyl/potteckit/config/Configs.java | 2 +- .../potteckit/mixin/inventory/MixinEntityPlayerSP.java | 4 ++-- src/main/resources/assets/potteckit/lang/en_us.lang | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java b/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java index 4558f8e..3c94034 100644 --- a/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java +++ b/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java @@ -129,7 +129,7 @@ public class Configs { @Config(types = Type.TOGGLE, domains = Domain.YEET) public static final HotkeyedBooleanConfig yeetTravelLightCheck = new HotkeyedBooleanConfig("yeet_travel_light_check", false, "", "yeet_travel_light_check", "yeet_travel_light_check"); @Config(types = Type.TOGGLE, domains = Domain.TWEAK) - public static final HotkeyedBooleanConfig swapElytraChestplate = new HotkeyedBooleanConfig("swap_elytra_chestplate", false, "", "swap_elytra_chestplate", "swap_elytra_chestplate"); + public static final HotkeyedBooleanConfig autoSwapElytraChestplate = new HotkeyedBooleanConfig("swap_elytra_chestplate", false, "", "swap_elytra_chestplate", "swap_elytra_chestplate"); public static void registerOnInit() { JsonModConfig jsonModConfig = new JsonModConfig(Reference.MOD_INFO, Reference.CONFIG_VERSION, ConfigHandler.optionCategoryList); diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java index 9dc3e99..5d1669f 100644 --- a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java +++ b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java @@ -36,7 +36,7 @@ public MixinEntityPlayerSP(World worldIn, GameProfile playerProfile) { @Inject(method = "onLivingUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;getItemStackFromSlot(Lnet/minecraft/inventory/EntityEquipmentSlot;)Lnet/minecraft/item/ItemStack;")) public void autoDeployElytra(CallbackInfo ci) { - if (Configs.enablePotteckit.getBooleanValue() && Configs.swapElytraChestplate.getBooleanValue()) { + if (Configs.enablePotteckit.getBooleanValue() && Configs.autoSwapElytraChestplate.getBooleanValue()) { ItemStack chestStack = getItemStackFromSlot(EntityEquipmentSlot.CHEST); if (chestStack.getItem() instanceof ItemArmor) { ItemStack elytraStack = ItemStack.EMPTY; @@ -90,7 +90,7 @@ public void autoDeployElytra(CallbackInfo ci) { @Inject(method = "notifyDataManagerChange", at = @At(value = "RETURN")) public void autoDeployChestplate(DataParameter key, CallbackInfo ci) { - if (Configs.enablePotteckit.getBooleanValue() && Configs.swapElytraChestplate.getBooleanValue()) { + if (Configs.enablePotteckit.getBooleanValue() && Configs.autoSwapElytraChestplate.getBooleanValue()) { if (FLAGS.equals(key) && !isElytraFlying() && wasFallFlying) { // the new data have been refreshed during EntityDataManager.setEntryValue() ItemStack elytraStack = getItemStackFromSlot(EntityEquipmentSlot.CHEST); diff --git a/src/main/resources/assets/potteckit/lang/en_us.lang b/src/main/resources/assets/potteckit/lang/en_us.lang index 19d4999..293b24e 100644 --- a/src/main/resources/assets/potteckit/lang/en_us.lang +++ b/src/main/resources/assets/potteckit/lang/en_us.lang @@ -110,5 +110,5 @@ potteckit.config.comment.protect_creative_slots=Protects the items at the given potteckit.config.name.protect_creative_slot_list=Protect Creative Slot List potteckit.config.comment.protect_creative_slot_list=The list of items to be protected by the config "Protect Creative Slots". -potteckit.config.name.swap_elytra_chestplate=Swap Elytra Chestplate -potteckit.config.comment.swap_elytra_chestplate=Automatically swaps between Elytra and Chestplates when the player is taking off or landing. +potteckit.config.name.swap_elytra_chestplate=Auto Swap Elytra Chestplate +potteckit.config.comment.swap_elytra_chestplate=Automatically swaps an elytra to the slot of chestplate, when the player has been equipped with a chestplate and is taking off.\nAutomatically swaps back when the player has just landed. From f4badd16956fa4639b29d06b837980a10e23c833 Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Sat, 2 Nov 2024 23:19:33 +0800 Subject: [PATCH 12/15] Plays equip sound when auto equipping elytra --- .../potteckit/mixin/inventory/MixinEntityPlayerSP.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java index 5d1669f..fa5c5af 100644 --- a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java +++ b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java @@ -82,6 +82,7 @@ public void autoDeployElytra(CallbackInfo ci) { InventoryUtils.clickSlot(inventoryContainer, chestSlot, currentItem, ClickType.SWAP); InventoryUtils.clickSlot(inventoryContainer, elytraSlot, currentItem, ClickType.SWAP); } + playEquipSound(elytraStack); potatoTechKit$cachedChestStack = chestStack; } } @@ -125,6 +126,7 @@ public void autoDeployChestplate(DataParameter key, CallbackInfo ci) { InventoryUtils.clickSlot(inventoryContainer, elytraSlot, currentItem, ClickType.SWAP); InventoryUtils.clickSlot(inventoryContainer, chestSlot, currentItem, ClickType.SWAP); } + playEquipSound(chestStack); potatoTechKit$cachedChestStack = ItemStack.EMPTY; } } From f9c602b3822b6e3ed49a9dec6bf5b6f3fd04eddf Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Tue, 5 Nov 2024 23:25:13 +0800 Subject: [PATCH 13/15] Checks player.inWater when auto equipping elytra --- .../mixin/inventory/MixinEntityPlayerSP.java | 90 ++++++++++--------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java index fa5c5af..0349fc9 100644 --- a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java +++ b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java @@ -37,53 +37,55 @@ public MixinEntityPlayerSP(World worldIn, GameProfile playerProfile) { @Inject(method = "onLivingUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;getItemStackFromSlot(Lnet/minecraft/inventory/EntityEquipmentSlot;)Lnet/minecraft/item/ItemStack;")) public void autoDeployElytra(CallbackInfo ci) { if (Configs.enablePotteckit.getBooleanValue() && Configs.autoSwapElytraChestplate.getBooleanValue()) { - ItemStack chestStack = getItemStackFromSlot(EntityEquipmentSlot.CHEST); - if (chestStack.getItem() instanceof ItemArmor) { - ItemStack elytraStack = ItemStack.EMPTY; - Slot elytraSlot = null; - int prevDurability = 0; - boolean prevMending = false; - for (int i = -1; i < 36; ++i) { - int id = i == -1 ? 45 : (i < 9 ? i + 36 : i); - Slot currSlot = inventoryContainer.getSlot(id); - ItemStack currStack = currSlot.getStack(); - if (!currStack.isEmpty() && currStack.getItem() == Items.ELYTRA) { - int level = EnchantmentHelper.getEnchantmentLevel(Enchantments.UNBREAKING, currStack); - int damage = currStack.getItemDamage(); - boolean mending = EnchantmentHelper.getEnchantmentLevel(Enchantments.MENDING, currStack) > 0; - int durability = (currStack.getMaxDamage() - damage) * (level + 1); - // find the first of the best elytra(s): - // best remaining durability: (remaining durability) * (unbreaking grade) - // mending is better - if (elytraStack.isEmpty() - || durability > prevDurability - || durability == prevDurability && !prevMending && mending) { - elytraSlot = currSlot; - elytraStack = currStack; - prevDurability = durability; - prevMending = mending; - } - if (mending && level >= Enchantments.UNBREAKING.getMaxLevel() && damage == 0) { - // the perfect elytra - break; + if (isInWater()) { + ItemStack chestStack = getItemStackFromSlot(EntityEquipmentSlot.CHEST); + if (chestStack.getItem() instanceof ItemArmor) { + ItemStack elytraStack = ItemStack.EMPTY; + Slot elytraSlot = null; + int prevDurability = 0; + boolean prevMending = false; + for (int i = -1; i < 36; ++i) { + int id = i == -1 ? 45 : (i < 9 ? i + 36 : i); + Slot currSlot = inventoryContainer.getSlot(id); + ItemStack currStack = currSlot.getStack(); + if (!currStack.isEmpty() && currStack.getItem() == Items.ELYTRA) { + int level = EnchantmentHelper.getEnchantmentLevel(Enchantments.UNBREAKING, currStack); + int damage = currStack.getItemDamage(); + boolean mending = EnchantmentHelper.getEnchantmentLevel(Enchantments.MENDING, currStack) > 0; + int durability = (currStack.getMaxDamage() - damage) * (level + 1); + // find the first of the best elytra(s): + // best remaining durability: (remaining durability) * (unbreaking grade) + // mending is better + if (elytraStack.isEmpty() + || durability > prevDurability + || durability == prevDurability && !prevMending && mending) { + elytraSlot = currSlot; + elytraStack = currStack; + prevDurability = durability; + prevMending = mending; + } + if (mending && level >= Enchantments.UNBREAKING.getMaxLevel() && damage == 0) { + // the perfect elytra + break; + } } } - } - if (elytraSlot != null && !elytraStack.isEmpty()) { - //swap Elytra & Chestplate - Slot chestSlot = inventoryContainer.getSlot(6); - int slotNumber = elytraSlot.slotNumber; - if (slotNumber >= 36 && slotNumber < 45) { - // hot-bar - InventoryUtils.clickSlot(inventoryContainer, chestSlot, slotNumber - 36, ClickType.SWAP); - } else { - int currentItem = inventory.currentItem; - InventoryUtils.clickSlot(inventoryContainer, elytraSlot, currentItem, ClickType.SWAP); - InventoryUtils.clickSlot(inventoryContainer, chestSlot, currentItem, ClickType.SWAP); - InventoryUtils.clickSlot(inventoryContainer, elytraSlot, currentItem, ClickType.SWAP); + if (elytraSlot != null && !elytraStack.isEmpty()) { + //swap Elytra & Chestplate + Slot chestSlot = inventoryContainer.getSlot(6); + int slotNumber = elytraSlot.slotNumber; + if (slotNumber >= 36 && slotNumber < 45) { + // hot-bar + InventoryUtils.clickSlot(inventoryContainer, chestSlot, slotNumber - 36, ClickType.SWAP); + } else { + int currentItem = inventory.currentItem; + InventoryUtils.clickSlot(inventoryContainer, elytraSlot, currentItem, ClickType.SWAP); + InventoryUtils.clickSlot(inventoryContainer, chestSlot, currentItem, ClickType.SWAP); + InventoryUtils.clickSlot(inventoryContainer, elytraSlot, currentItem, ClickType.SWAP); + } + playEquipSound(elytraStack); + potatoTechKit$cachedChestStack = chestStack; } - playEquipSound(elytraStack); - potatoTechKit$cachedChestStack = chestStack; } } } From 9c1982e757eee2485cb0191aa48c0f4e06119ebc Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Wed, 6 Nov 2024 00:03:27 +0800 Subject: [PATCH 14/15] Checks !player.inWater when auto equipping elytra --- .../potteckit/mixin/inventory/MixinEntityPlayerSP.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java index 0349fc9..50b7263 100644 --- a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java +++ b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java @@ -37,7 +37,7 @@ public MixinEntityPlayerSP(World worldIn, GameProfile playerProfile) { @Inject(method = "onLivingUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;getItemStackFromSlot(Lnet/minecraft/inventory/EntityEquipmentSlot;)Lnet/minecraft/item/ItemStack;")) public void autoDeployElytra(CallbackInfo ci) { if (Configs.enablePotteckit.getBooleanValue() && Configs.autoSwapElytraChestplate.getBooleanValue()) { - if (isInWater()) { + if (!isInWater()) { ItemStack chestStack = getItemStackFromSlot(EntityEquipmentSlot.CHEST); if (chestStack.getItem() instanceof ItemArmor) { ItemStack elytraStack = ItemStack.EMPTY; From 9982d92c2f4eb7c7bc2eade90759a6ae9443eb73 Mon Sep 17 00:00:00 2001 From: Natfalluvia Date: Sun, 10 Nov 2024 18:14:09 +0800 Subject: [PATCH 15/15] Add config "F3 Cursor with Attack Indicator" --- .../potteckit/config/Configs.java | 2 + .../mixin/meters/MixinGuiIngame.java | 65 +++++++++++++++++++ .../assets/potteckit/lang/en_us.lang | 3 + src/main/resources/mixins.potteckit.json | 1 + 4 files changed, 71 insertions(+) create mode 100644 src/main/java/io/github/rainyaphthyl/potteckit/mixin/meters/MixinGuiIngame.java diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java b/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java index 3c94034..5266852 100644 --- a/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java +++ b/src/main/java/io/github/rainyaphthyl/potteckit/config/Configs.java @@ -130,6 +130,8 @@ public class Configs { public static final HotkeyedBooleanConfig yeetTravelLightCheck = new HotkeyedBooleanConfig("yeet_travel_light_check", false, "", "yeet_travel_light_check", "yeet_travel_light_check"); @Config(types = Type.TOGGLE, domains = Domain.TWEAK) public static final HotkeyedBooleanConfig autoSwapElytraChestplate = new HotkeyedBooleanConfig("swap_elytra_chestplate", false, "", "swap_elytra_chestplate", "swap_elytra_chestplate"); + @Config(types = Type.TOGGLE, domains = Domain.METER) + public static final HotkeyedBooleanConfig f3CursorAttackIndicator = new HotkeyedBooleanConfig("f3_cursor_attack_indicator", false, "", "f3_cursor_attack_indicator", "f3_cursor_attack_indicator"); public static void registerOnInit() { JsonModConfig jsonModConfig = new JsonModConfig(Reference.MOD_INFO, Reference.CONFIG_VERSION, ConfigHandler.optionCategoryList); diff --git a/src/main/java/io/github/rainyaphthyl/potteckit/mixin/meters/MixinGuiIngame.java b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/meters/MixinGuiIngame.java new file mode 100644 index 0000000..dfebfc7 --- /dev/null +++ b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/meters/MixinGuiIngame.java @@ -0,0 +1,65 @@ +package io.github.rainyaphthyl.potteckit.mixin.meters; + +import io.github.rainyaphthyl.potteckit.config.Configs; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiIngame; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.settings.GameSettings; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +@Mixin(GuiIngame.class) +public abstract class MixinGuiIngame extends Gui { + @Shadow + @Final + private Minecraft mc; + + @Inject(method = "renderAttackIndicator", locals = LocalCapture.CAPTURE_FAILSOFT, at = @At(value = "FIELD", target = "Lnet/minecraft/client/settings/GameSettings;showDebugInfo:Z", ordinal = 0), cancellable = true) + public void onRenderCrosshair(float partialTicks, ScaledResolution resolution, CallbackInfo ci, GameSettings gamesettings, int width, int height) { + if (Configs.enablePotteckit.getBooleanValue() && Configs.f3CursorAttackIndicator.getBooleanValue()) { + Entity entity = mc.getRenderViewEntity(); + if (entity != null) { + GlStateManager.pushMatrix(); + GlStateManager.translate((float) (width / 2), (float) (height / 2), zLevel); + GlStateManager.rotate(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTicks, -1.0F, 0.0F, 0.0F); + GlStateManager.rotate(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * partialTicks, 0.0F, 1.0F, 0.0F); + GlStateManager.scale(-1.0F, -1.0F, -1.0F); + OpenGlHelper.renderDirections(10); + GlStateManager.popMatrix(); + GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.ONE_MINUS_DST_COLOR, GlStateManager.DestFactor.ONE_MINUS_SRC_COLOR, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + GlStateManager.enableAlpha(); + //drawTexturedModalRect(width / 2 - 7, height / 2 - 7, 0, 0, 16, 16); + if (mc.gameSettings.attackIndicator == 1) { + float f = mc.player.getCooledAttackStrength(0.0F); + boolean flag = false; + if (mc.pointedEntity != null && mc.pointedEntity instanceof EntityLivingBase && f >= 1.0F) { + flag = mc.player.getCooldownPeriod() > 5.0F; + flag = flag & mc.pointedEntity.isEntityAlive(); + } + int i = height / 2 - 7 + 16; + int j = width / 2 - 8; + if (flag) { + drawTexturedModalRect(j, i, 68, 94, 16, 16); + } else if (f < 1.0F) { + int k = (int) (f * 17.0F); + drawTexturedModalRect(j, i, 36, 94, 16, 4); + drawTexturedModalRect(j, i, 52, 94, k, 4); + } + } + if (ci.isCancellable() && !ci.isCancelled()) { + ci.cancel(); + } + } + } + } +} diff --git a/src/main/resources/assets/potteckit/lang/en_us.lang b/src/main/resources/assets/potteckit/lang/en_us.lang index 293b24e..1e18a98 100644 --- a/src/main/resources/assets/potteckit/lang/en_us.lang +++ b/src/main/resources/assets/potteckit/lang/en_us.lang @@ -112,3 +112,6 @@ potteckit.config.comment.protect_creative_slot_list=The list of items to be prot potteckit.config.name.swap_elytra_chestplate=Auto Swap Elytra Chestplate potteckit.config.comment.swap_elytra_chestplate=Automatically swaps an elytra to the slot of chestplate, when the player has been equipped with a chestplate and is taking off.\nAutomatically swaps back when the player has just landed. + +potteckit.config.name.f3_cursor_attack_indicator=F3 Cursor with Attack Indicator +potteckit.config.comment.f3_cursor_attack_indicator=Always renders the F3 screen type cursor, meanwhile allows rendering the crosshair attack indicator (if it's enabled in the game settings). diff --git a/src/main/resources/mixins.potteckit.json b/src/main/resources/mixins.potteckit.json index 59170f3..031f5f4 100644 --- a/src/main/resources/mixins.potteckit.json +++ b/src/main/resources/mixins.potteckit.json @@ -28,6 +28,7 @@ "inventory.MixinEntityPlayerSP", "inventory.MixinGuiContainerCreative", "meters.MixinEntityPlayerSP", + "meters.MixinGuiIngame", "optifix.MixinPlayerList", "optifix.MixinWorldEntitySpawner", "render.MixinBlockRendererDispatcher",