diff --git a/ChangeLog.md b/ChangeLog.md index acfd952..1a1c4a7 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -48,3 +48,9 @@ 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. +2. Fix [MC-88179](https://bugs.mojang.com/browse/MC-88179): Armor bar disappears after changing dimension until GUI update. 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..5266852 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) @@ -110,6 +126,12 @@ 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"); + @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); @@ -118,6 +140,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/mixin/inventory/MixinEntityPlayerSP.java b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java new file mode 100644 index 0000000..50b7263 --- /dev/null +++ b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/inventory/MixinEntityPlayerSP.java @@ -0,0 +1,137 @@ +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.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.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; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(EntityPlayerSP.class) +public abstract class MixinEntityPlayerSP extends AbstractClientPlayer { + @Shadow + private boolean wasFallFlying; + @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.autoSwapElytraChestplate.getBooleanValue()) { + 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); + } + playEquipSound(elytraStack); + potatoTechKit$cachedChestStack = chestStack; + } + } + } + } + } + + @Inject(method = "notifyDataManagerChange", at = @At(value = "RETURN")) + public void autoDeployChestplate(DataParameter key, CallbackInfo ci) { + 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); + 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); + } + playEquipSound(chestStack); + potatoTechKit$cachedChestStack = ItemStack.EMPTY; + } + } + } + } +} 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/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..d4729ab --- /dev/null +++ b/src/main/java/io/github/rainyaphthyl/potteckit/mixin/render/MixinWorld.java @@ -0,0 +1,54 @@ +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.Unique; +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; + + @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()) { + 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); + } + } + } + } +} 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/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..1e18a98 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,12 +96,22 @@ 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\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 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. 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=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 0f8ba19..031f5f4 100644 --- a/src/main/resources/mixins.potteckit.json +++ b/src/main/resources/mixins.potteckit.json @@ -25,8 +25,10 @@ "gamephase.MixinWorldProvider", "gamephase.MixinWorldProviderEnd", "gamephase.MixinWorldServer", + "inventory.MixinEntityPlayerSP", "inventory.MixinGuiContainerCreative", "meters.MixinEntityPlayerSP", + "meters.MixinGuiIngame", "optifix.MixinPlayerList", "optifix.MixinWorldEntitySpawner", "render.MixinBlockRendererDispatcher", @@ -35,6 +37,7 @@ "render.MixinEntityRenderer", "render.MixinRenderChunk", "render.MixinRenderGlobal", + "render.MixinWorld", "sync.MixinEntityTrackerEntry", "sync.MixinNetHandlerPlayServer", "sync.MixinWorld",