Initial commit
This commit is contained in:
18
src/main/java/com/kasetoatz/superenchants/Superenchants.java
Normal file
18
src/main/java/com/kasetoatz/superenchants/Superenchants.java
Normal 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));
|
||||
}
|
||||
}
|
||||
169
src/main/java/com/kasetoatz/superenchants/config/Config.java
Normal file
169
src/main/java/com/kasetoatz/superenchants/config/Config.java
Normal 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."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
61
src/main/java/com/kasetoatz/superenchants/util/Util.java
Normal file
61
src/main/java/com/kasetoatz/superenchants/util/Util.java
Normal 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);
|
||||
}
|
||||
}
|
||||
24
src/main/resources/fabric.mod.json
Normal file
24
src/main/resources/fabric.mod.json
Normal 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}"
|
||||
}
|
||||
}
|
||||
24
src/main/resources/superenchants.mixins.json
Normal file
24
src/main/resources/superenchants.mixins.json
Normal 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user