Initial commit

This commit is contained in:
2025-09-18 13:29:02 +02:00
commit acdf1d5747
22 changed files with 1125 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
package com.kasetoatz.superenchants;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.minecraft.registry.RegistryKeys;
import static com.kasetoatz.superenchants.config.Config.load;
import static com.kasetoatz.superenchants.util.Util.REGISTRY;
public class Superenchants implements ModInitializer
{
@Override
public void onInitialize()
{
load();
ServerLifecycleEvents.SERVER_STARTED.register(server -> server.getOverworld().getRegistryManager().getOptional(RegistryKeys.ENCHANTMENT).ifPresent(enchantments -> REGISTRY = enchantments));
}
}

View File

@@ -0,0 +1,169 @@
package com.kasetoatz.superenchants.config;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.util.Identifier;
import net.minecraft.util.crash.CrashException;
import net.minecraft.util.crash.CrashReport;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
public class Config
{
public static boolean BOW_ENCHANTS_UNNERF = true;
public static boolean CROSSBOW_ENCHANTS_UNNERF = true;
public static boolean ARMOR_ENCHANTS_UNNERF = true;
public static boolean TOOL_ENCHANTS_UNNERF = true;
public static boolean ENABLE_CHANNELING_2 = true;
public static boolean ENABLE_LOYALTY_VOID_PROTECTION = true; // todo
public static boolean DISABLE_SOUL_SPEED_DAMAGE = true;
public static boolean DISABLE_THORNS_DAMAGE = true;
public static boolean ENABLE_INFINITY_WITHOUT_ARROW = true;
public static boolean ENABLE_CROSSBOW_INFINITY = true;
public static boolean LOYALTY_RETURN_TO_SAME_SLOT = true; // todo
public static boolean ENABLE_CUSTOM_ENCHANT_LEVELS = true;
public static Map<Identifier, Integer> LEVELS = new HashMap<>(Map.ofEntries(
Map.entry(Identifier.of("minecraft:unbreaking"), 5),
Map.entry(Identifier.of("minecraft:thorns"), 5),
Map.entry(Identifier.of("minecraft:respiration"), 5),
Map.entry(Identifier.of("minecraft:swift_sneak"), 5),
Map.entry(Identifier.of("minecraft:feather_falling"), 10),
Map.entry(Identifier.of("minecraft:soul_speed"), 5),
Map.entry(Identifier.of("minecraft:protection"), 10),
Map.entry(Identifier.of("minecraft:projectile_protection"), 10),
Map.entry(Identifier.of("minecraft:fire_protection"), 10),
Map.entry(Identifier.of("minecraft:blast_protection"), 10),
Map.entry(Identifier.of("minecraft:depth_strider"), 5),
Map.entry(Identifier.of("minecraft:fire_aspect"), 3),
Map.entry(Identifier.of("minecraft:looting"), 5),
Map.entry(Identifier.of("minecraft:knockback"), 3),
Map.entry(Identifier.of("minecraft:sweeping_edge"), 5),
Map.entry(Identifier.of("minecraft:sharpness"), 10),
Map.entry(Identifier.of("minecraft:smite"), 10),
Map.entry(Identifier.of("minecraft:bane_of_arthropods"), 10),
Map.entry(Identifier.of("minecraft:wind_burst"), 5),
Map.entry(Identifier.of("minecraft:density"), 10),
Map.entry(Identifier.of("minecraft:breach"), 10),
Map.entry(Identifier.of("minecraft:efficiency"), 10),
Map.entry(Identifier.of("minecraft:fortune"), 5),
Map.entry(Identifier.of("minecraft:power"), 10),
Map.entry(Identifier.of("minecraft:punch"), 3),
Map.entry(Identifier.of("minecraft:lure"), 5),
Map.entry(Identifier.of("minecraft:luck_of_the_sea"), 5),
Map.entry(Identifier.of("minecraft:impaling"), 10),
Map.entry(Identifier.of("minecraft:loyalty"), 5),
Map.entry(Identifier.of("minecraft:riptide"), 5),
Map.entry(Identifier.of("minecraft:quick_charge"), 5),
Map.entry(Identifier.of("minecraft:piercing"), 10)
));
private static final Path FILE = FabricLoader.getInstance().getConfigDir().resolve("superenchants.json");
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
public static void load()
{
if (!Files.exists(FILE))
{
save();
return;
}
try
{
String json = Files.readString(FILE);
JsonObject data = GSON.fromJson(json, JsonObject.class);
if (data.has("bow-enchants-unnerf"))
{
BOW_ENCHANTS_UNNERF = data.get("bow-enchants-unnerf").getAsBoolean();
}
if (data.has("crossbow-enchants-unnerf"))
{
CROSSBOW_ENCHANTS_UNNERF = data.get("crossbow-enchants-unnerf").getAsBoolean();
}
if (data.has("armor-enchants-unnerf"))
{
ARMOR_ENCHANTS_UNNERF = data.get("armor-enchants-unnerf").getAsBoolean();
}
if (data.has("tool-enchants-unnerf"))
{
TOOL_ENCHANTS_UNNERF = data.get("tool-enchants-unnerf").getAsBoolean();
}
if (data.has("enable-channeling-2"))
{
ENABLE_CHANNELING_2 = data.get("enable-channeling-2").getAsBoolean();
}
if (data.has("enable-loyalty-void-protection"))
{
ENABLE_LOYALTY_VOID_PROTECTION = data.get("enable-loyalty-void-protection").getAsBoolean();
}
if (data.has("disable-soul-speed-damage"))
{
DISABLE_SOUL_SPEED_DAMAGE = data.get("disable-soul-speed-damage").getAsBoolean();
}
if (data.has("disable-thorns-damage"))
{
DISABLE_THORNS_DAMAGE = data.get("disable-thorns-damage").getAsBoolean();
}
if (data.has("enable-infinity-without-arrow"))
{
ENABLE_INFINITY_WITHOUT_ARROW = data.get("enable-infinity-without-arrow").getAsBoolean();
}
if (data.has("enable-crossbow-infinity"))
{
ENABLE_CROSSBOW_INFINITY = data.get("enable-crossbow-infinity").getAsBoolean();
}
if (data.has("loyalty-return-to-same-slot"))
{
LOYALTY_RETURN_TO_SAME_SLOT = data.get("loyalty-return-to-same-slot").getAsBoolean();
}
if (data.has("enable-custom-enchant-levels"))
{
ENABLE_CUSTOM_ENCHANT_LEVELS = data.get("enable-custom-enchant-levels").getAsBoolean();
}
if (data.has("custom-levels"))
{
JsonObject levels = data.get("custom-levels").getAsJsonObject();
levels.entrySet().forEach((entry) -> LEVELS.put(Identifier.of(entry.getKey()), entry.getValue().getAsInt()));
}
save();
}
catch (IOException exc)
{
throw new CrashException(CrashReport.create(exc, "Loading config file."));
}
}
private static void save()
{
try
{
JsonObject data = new JsonObject();
data.addProperty("bow-enchants-unnerf", BOW_ENCHANTS_UNNERF);
data.addProperty("crossbow-enchants-unnerf", CROSSBOW_ENCHANTS_UNNERF);
data.addProperty("armor-enchants-unnerf", ARMOR_ENCHANTS_UNNERF);
data.addProperty("tool-enchants-unnerf", TOOL_ENCHANTS_UNNERF);
data.addProperty("enable-channeling-2", ENABLE_CHANNELING_2);
data.addProperty("enable-loyalty-void-protection", ENABLE_LOYALTY_VOID_PROTECTION);
data.addProperty("disable-soul-speed-damage", DISABLE_SOUL_SPEED_DAMAGE);
data.addProperty("disable-thorns-damage", DISABLE_THORNS_DAMAGE);
data.addProperty("enable-infinity-without-arrow", ENABLE_INFINITY_WITHOUT_ARROW);
data.addProperty("enable-crossbow-infinity", ENABLE_CROSSBOW_INFINITY);
data.addProperty("loyalty-return-to-same-slot", LOYALTY_RETURN_TO_SAME_SLOT);
data.addProperty("enable-custom-enchant-levels", ENABLE_CUSTOM_ENCHANT_LEVELS);
JsonObject levels = new JsonObject();
LEVELS.forEach((id, level) -> levels.addProperty(id.toString(), level));
data.add("custom-levels", levels);
Files.writeString(FILE, GSON.toJson(data));
}
catch (IOException exc)
{
throw new CrashException(CrashReport.create(exc, "Saving config file."));
}
}
}

View File

@@ -0,0 +1,29 @@
package com.kasetoatz.superenchants.mixin;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.item.BowItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import static com.kasetoatz.superenchants.util.Util.getLevel;
import static com.kasetoatz.superenchants.config.Config.ENABLE_INFINITY_WITHOUT_ARROW;
@Mixin(BowItem.class)
public class BowItemMixin
{
@ModifyExpressionValue(method="use", at=@At(value="INVOKE", target="Lnet/minecraft/item/ItemStack;isEmpty()Z"))
public boolean use(boolean original, @Local ItemStack stack)
{
return (!ENABLE_INFINITY_WITHOUT_ARROW || getLevel(Enchantments.INFINITY, stack) == 0) && original;
}
@ModifyExpressionValue(method="onStoppedUsing", at=@At(value="INVOKE", target="Lnet/minecraft/entity/player/PlayerEntity;getProjectileType(Lnet/minecraft/item/ItemStack;)Lnet/minecraft/item/ItemStack;"))
public ItemStack onStoppedUsing(ItemStack original, @Local(argsOnly=true) ItemStack stack)
{
return (ENABLE_INFINITY_WITHOUT_ARROW && getLevel(Enchantments.INFINITY, stack) > 0) ? new ItemStack(Items.ARROW) : original;
}
}

View File

@@ -0,0 +1,29 @@
package com.kasetoatz.superenchants.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.enchantment.EnchantmentEffectContext;
import net.minecraft.enchantment.effect.entity.ChangeItemDamageEnchantmentEffect;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import static com.kasetoatz.superenchants.config.Config.DISABLE_SOUL_SPEED_DAMAGE;
import static com.kasetoatz.superenchants.config.Config.DISABLE_THORNS_DAMAGE;
@Mixin(ChangeItemDamageEnchantmentEffect.class)
public class ChangeItemDamageEnchantmentEffectMixin
{
@ModifyArg(method="apply", at=@At(value="INVOKE", target="Lnet/minecraft/item/ItemStack;damage(ILnet/minecraft/server/world/ServerWorld;Lnet/minecraft/server/network/ServerPlayerEntity;Ljava/util/function/Consumer;)V"), index=0)
public int damage(int amount, @Local(argsOnly=true) EnchantmentEffectContext context)
{
if (DISABLE_SOUL_SPEED_DAMAGE && amount == 1)
{
return 0;
}
else if (DISABLE_THORNS_DAMAGE && amount == 2)
{
return 0;
}
return amount;
}
}

View File

@@ -0,0 +1,66 @@
package com.kasetoatz.superenchants.mixin;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.item.CrossbowItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.Unit;
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.ModifyArg;
import java.util.List;
import static com.kasetoatz.superenchants.config.Config.ENABLE_CROSSBOW_INFINITY;
import static com.kasetoatz.superenchants.config.Config.ENABLE_INFINITY_WITHOUT_ARROW;
import static com.kasetoatz.superenchants.util.Util.getLevel;
@Mixin(CrossbowItem.class)
public class CrossbowItemMixin
{
@ModifyExpressionValue(method="use", at=@At(value="INVOKE", target="Lnet/minecraft/item/ItemStack;isEmpty()Z"))
public boolean use(boolean original, @Local ItemStack stack)
{
if (ENABLE_CROSSBOW_INFINITY && ENABLE_INFINITY_WITHOUT_ARROW && getLevel(Enchantments.INFINITY, stack) > 0)
{
return false;
}
return original;
}
@ModifyExpressionValue(method="loadProjectiles", at=@At(value="INVOKE", target="Ljava/util/List;isEmpty()Z"))
private static boolean isEmpty(boolean original, @Local(argsOnly=true) ItemStack stack)
{
if (ENABLE_CROSSBOW_INFINITY && ENABLE_INFINITY_WITHOUT_ARROW && getLevel(Enchantments.INFINITY, stack) > 0)
{
return false;
}
return original;
}
@Unique
private static ItemStack createArrow()
{
ItemStack stack = new ItemStack(Items.ARROW);
stack.set(DataComponentTypes.INTANGIBLE_PROJECTILE, Unit.INSTANCE);
return stack;
}
@ModifyArg(method="loadProjectiles", at=@At(value="INVOKE", target="Lnet/minecraft/component/type/ChargedProjectilesComponent;of(Ljava/util/List;)Lnet/minecraft/component/type/ChargedProjectilesComponent;"))
private static List<ItemStack> projectile(List<ItemStack> projectiles, @Local(argsOnly = true) ItemStack stack)
{
if (ENABLE_CROSSBOW_INFINITY && ENABLE_INFINITY_WITHOUT_ARROW && getLevel(Enchantments.INFINITY, stack) > 0 && projectiles.stream().noneMatch(item -> item.getItem() == Items.FIREWORK_ROCKET))
{
if (getLevel(Enchantments.MULTISHOT, stack) > 0)
{
return List.of(createArrow(), createArrow(), createArrow());
}
return List.of(createArrow());
}
return projectiles;
}
}

View File

@@ -0,0 +1,104 @@
package com.kasetoatz.superenchants.mixin;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.entry.RegistryEntry;
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.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
import static com.kasetoatz.superenchants.config.Config.*;
import static com.kasetoatz.superenchants.util.Util.getCustomLevel;
import static com.kasetoatz.superenchants.util.Util.getEnchantment;
@Mixin(Enchantment.class)
public class EnchantmentMixin
{
@Shadow @Final private Enchantment.Definition definition;
@Unique private static final List<RegistryKey<Enchantment>> BOW_ENCHANTS = List.of(Enchantments.INFINITY, Enchantments.MENDING);
@Unique private static final List<RegistryKey<Enchantment>> CROSSBOW_ENCHANTS = List.of(Enchantments.PIERCING, Enchantments.MULTISHOT);
@Unique private static final List<RegistryKey<Enchantment>> TOOL_ENCHANTS = List.of(Enchantments.SHARPNESS, Enchantments.SMITE, Enchantments.BANE_OF_ARTHROPODS);
@Unique private static final List<RegistryKey<Enchantment>> ARMOR_ENCHANTS = List.of(Enchantments.PROTECTION, Enchantments.BLAST_PROTECTION, Enchantments.FIRE_PROTECTION, Enchantments.PROJECTILE_PROTECTION);
@Inject(method="canBeCombined", at=@At("HEAD"), cancellable = true)
private static void canBeCombined(RegistryEntry<Enchantment> first, RegistryEntry<Enchantment> second, CallbackInfoReturnable<Boolean> cir)
{
if (
(BOW_ENCHANTS_UNNERF && BOW_ENCHANTS.stream().anyMatch(first::matchesKey) && BOW_ENCHANTS.stream().anyMatch(second::matchesKey)) ||
(CROSSBOW_ENCHANTS_UNNERF && CROSSBOW_ENCHANTS.stream().anyMatch(first::matchesKey) && CROSSBOW_ENCHANTS.stream().anyMatch(second::matchesKey)) ||
(ARMOR_ENCHANTS_UNNERF && ARMOR_ENCHANTS.stream().anyMatch(first::matchesKey) && ARMOR_ENCHANTS.stream().anyMatch(second::matchesKey)) ||
(TOOL_ENCHANTS_UNNERF && TOOL_ENCHANTS.stream().anyMatch(first::matchesKey) && TOOL_ENCHANTS.stream().anyMatch(second::matchesKey))
)
{
cir.setReturnValue(true);
}
}
@ModifyReturnValue(method="getMaxLevel", at=@At("RETURN"))
public int getMaxLevel(int original)
{
Enchantment enchantment = (Enchantment)(Object)this;
int level = getCustomLevel(enchantment);
if (level > 0)
{
return level;
}
return original;
}
@Unique
private int getPowerLevel(int level)
{
int newMax = getCustomLevel((Enchantment)(Object)this);
if (newMax == 0)
{
return level;
}
return (int)(level / (newMax / (double)definition.maxLevel()) - 1);
}
@ModifyArg(method="getMinPower", at=@At(value="INVOKE", target="Lnet/minecraft/enchantment/Enchantment$Cost;forLevel(I)I"))
public int minPow(int level)
{
return getPowerLevel(level);
}
@ModifyArg(method="getMaxPower", at=@At(value="INVOKE", target="Lnet/minecraft/enchantment/Enchantment$Cost;forLevel(I)I"))
public int maxPow(int level)
{
return getPowerLevel(level);
}
@ModifyReturnValue(method="isAcceptableItem", at=@At("RETURN"))
public boolean isAcceptableItem(boolean original, @Local(argsOnly=true) ItemStack stack)
{
if (!ENABLE_CROSSBOW_INFINITY || !stack.isOf(Items.CROSSBOW))
{
return original;
}
Enchantment self = (Enchantment)(Object)this;
RegistryEntry.Reference<Enchantment> enchantment = getEnchantment(Enchantments.INFINITY);
if (enchantment == null)
{
return original;
}
if (self.equals(enchantment.value()))
{
return true;
}
return original;
}
}

View File

@@ -0,0 +1,30 @@
package com.kasetoatz.superenchants.mixin;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.projectile.PersistentProjectileEntity;
import net.minecraft.entity.projectile.TridentEntity;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(PersistentProjectileEntity.class)
public class PersistentProjectileMixin
{
@Redirect(method="tryPickup", at= @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerInventory;insertStack(Lnet/minecraft/item/ItemStack;)Z"))
public boolean tryPickup(PlayerInventory inventory, ItemStack stack)
{
if ((Object)this instanceof TridentEntity trident)
{
int slot = trident.get(DataComponentTypes.CUSTOM_DATA).copyNbt().getInt("slot", -1);
if (slot == PlayerInventory.OFF_HAND_SLOT)
{
inventory.setStack(slot, stack);
return true;
}
return inventory.insertStack(slot, stack);
}
return inventory.insertStack(stack);
}
}

View File

@@ -0,0 +1,30 @@
package com.kasetoatz.superenchants.mixin;
import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.projectile.TridentEntity;
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 static com.kasetoatz.superenchants.config.Config.ENABLE_LOYALTY_VOID_PROTECTION;
@Mixin(TridentEntity.class)
public abstract class TridentEntityMixin
{
@Shadow @Final private static TrackedData<Byte> LOYALTY;
@Shadow private boolean dealtDamage;
@Inject(method="tick", at=@At("HEAD"))
public void tick(CallbackInfo ci)
{
TridentEntity trident = ((TridentEntity)(Object)this);
if (ENABLE_LOYALTY_VOID_PROTECTION && trident.getDataTracker().get(LOYALTY) > 0 && trident.getY() <= trident.getWorld().getBottomY())
{
dealtDamage = true;
trident.setVelocity(0, 0, 0);
}
}
}

View File

@@ -0,0 +1,28 @@
package com.kasetoatz.superenchants.mixin;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.NbtComponent;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.item.TridentItem;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(TridentItem.class)
public class TridentItemMixin
{
@Inject(method="onStoppedUsing", at=@At(value="INVOKE", target="Lnet/minecraft/item/ItemStack;splitUnlessCreative(ILnet/minecraft/entity/LivingEntity;)Lnet/minecraft/item/ItemStack;"))
public void splitUnlessCreative(ItemStack stack, World world, LivingEntity user, int remainingUseTicks, CallbackInfoReturnable<Boolean> cir)
{
if (user instanceof PlayerEntity player)
{
int slot = (player.getOffHandStack() == stack) ? PlayerInventory.OFF_HAND_SLOT : player.getInventory().getSlotWithStack(stack);
stack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.DEFAULT.apply(nbt -> nbt.putInt("slot", slot)));
}
}
}

View File

@@ -0,0 +1,24 @@
package com.kasetoatz.superenchants.mixin;
import net.minecraft.entity.projectile.TridentEntity;
import net.minecraft.loot.condition.WeatherCheckLootCondition;
import net.minecraft.loot.context.LootContext;
import net.minecraft.loot.context.LootContextParameters;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(WeatherCheckLootCondition.class)
public class WeatherCheckLootConditionMixin
{
@Inject(method="test(Lnet/minecraft/loot/context/LootContext;)Z", at=@At("RETURN"), cancellable=true)
public void test(LootContext lootContext, CallbackInfoReturnable<Boolean> cir)
{
Integer level = lootContext.get(LootContextParameters.ENCHANTMENT_LEVEL);
if (lootContext.get(LootContextParameters.DIRECT_ATTACKING_ENTITY) instanceof TridentEntity && level != null && level > 1)
{
cir.setReturnValue(true);
}
}
}

View File

@@ -0,0 +1,61 @@
package com.kasetoatz.superenchants.util;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.Identifier;
import java.util.Optional;
import static com.kasetoatz.superenchants.config.Config.*;
public class Util
{
public static Registry<Enchantment> REGISTRY;
public static int getCustomLevel(Enchantment enchantment)
{
if (REGISTRY == null)
{
return 0;
}
Optional<RegistryKey<Enchantment>> key = REGISTRY.getKey(enchantment);
if (key.isEmpty())
{
return 0;
}
if (ENABLE_CHANNELING_2 && key.map(registryKey -> registryKey.equals(Enchantments.CHANNELING)).orElse(false))
{
return 2;
}
Identifier id = key.get().getValue();
if (ENABLE_CUSTOM_ENCHANT_LEVELS && LEVELS.containsKey(id))
{
return LEVELS.get(id);
}
return 0;
}
public static RegistryEntry.Reference<Enchantment> getEnchantment(RegistryKey<Enchantment> key)
{
if (REGISTRY == null)
{
return null;
}
return REGISTRY.getEntry(key.getValue()).orElse(null);
}
public static int getLevel(RegistryKey<Enchantment> key, ItemStack stack)
{
RegistryEntry.Reference<Enchantment> enchantment = getEnchantment(key);
if (enchantment == null)
{
return 0;
}
return EnchantmentHelper.getLevel(enchantment, stack);
}
}

View File

@@ -0,0 +1,24 @@
{
"schemaVersion": 1,
"id": "superenchants",
"version": "${version}",
"name": "SuperEnchants",
"description": "",
"authors": [],
"contact": {},
"license": "MIT",
"environment": "server",
"entrypoints": {
"main": [
"com.kasetoatz.superenchants.Superenchants"
]
},
"mixins": [
"superenchants.mixins.json"
],
"depends": {
"fabricloader": ">=${loader_version}",
"fabric": "*",
"minecraft": "${minecraft_version}"
}
}

View File

@@ -0,0 +1,24 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.kasetoatz.superenchants.mixin",
"compatibilityLevel": "JAVA_21",
"mixins": [
"BowItemMixin",
"ChangeItemDamageEnchantmentEffectMixin",
"CrossbowItemMixin",
"EnchantmentMixin",
"PersistentProjectileMixin",
"TridentEntityMixin",
"TridentItemMixin",
"WeatherCheckLootConditionMixin"
],
"client": [
],
"injectors": {
"defaultRequire": 1
},
"overwrites": {
"requireAnnotations": true
}
}