diff --git a/src/main/java/xyz/nearmisses/patience/mc_rebalance/EnchantGen.java b/src/main/java/xyz/nearmisses/patience/mc_rebalance/EnchantGen.java new file mode 100644 index 0000000..1efbe4d --- /dev/null +++ b/src/main/java/xyz/nearmisses/patience/mc_rebalance/EnchantGen.java @@ -0,0 +1,60 @@ +package xyz.nearmisses.patience.mc_rebalance; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricDynamicRegistryProvider; +import net.fabricmc.fabric.api.resource.conditions.v1.ResourceCondition; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.entity.EquipmentSlotGroup; +import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.EnchantmentEffectComponents; +import net.minecraft.world.item.enchantment.EnchantmentTarget; +import net.minecraft.world.item.enchantment.LevelBasedValue; +import org.jetbrains.annotations.NotNull; +import xyz.nearmisses.patience.mc_rebalance.enchantment.effect.WindupEffect; + +import java.util.concurrent.CompletableFuture; + +// So this is how Java likes to do data generation. Cool? +// I don't like this specific organisation, though. +public class EnchantGen extends FabricDynamicRegistryProvider { + public EnchantGen(FabricDataOutput output, CompletableFuture registriesFuture) { + super(output, registriesFuture); + System.out.println("Generating enchantments"); + } + + @Override + protected void configure(HolderLookup.Provider registries, Entries entries) { + // Our new enchantment + register(entries, ModEnchantments.Windup, + Enchantment.enchantment( + Enchantment.definition( + registries.lookupOrThrow(Registries.ITEM).getOrThrow(ItemTags.WEAPON_ENCHANTABLE), // Valid items + 10, // Weight (irrelevant for us?) + 1, // Max enchant level + Enchantment.dynamicCost(2, 10), // Base cost for level 1 + Enchantment.dynamicCost(12, 20), // same but for max cost + 5, // Anvil cost + EquipmentSlotGroup.HAND // Valid slots to work in + ) + ).withEffect( + EnchantmentEffectComponents.POST_ATTACK, // enchantment occurs POST_ATTACK + //EnchantmentEffectComponents.DAMAGE, + EnchantmentTarget.ATTACKER, + EnchantmentTarget.VICTIM, + new WindupEffect(LevelBasedValue.constant(0.8f)) //.perLevel(0.8f, 0.2f)) // scale the enchantment linearly (irrelevant). + ) + ); + } + + private void register(Entries entries, ResourceKey key, Enchantment.Builder builder, ResourceCondition... resourceConditions) { + entries.add(key, builder.build(key.location()), resourceConditions); + } + + @Override + public @NotNull String getName() { + return "MCRebalanceEnchantGen"; + } +} diff --git a/src/main/java/xyz/nearmisses/patience/mc_rebalance/MCRebalance.java b/src/main/java/xyz/nearmisses/patience/mc_rebalance/MCRebalance.java index f06ac24..882817e 100644 --- a/src/main/java/xyz/nearmisses/patience/mc_rebalance/MCRebalance.java +++ b/src/main/java/xyz/nearmisses/patience/mc_rebalance/MCRebalance.java @@ -18,6 +18,7 @@ public class MCRebalance implements ModInitializer { ModItems.init(); // Initialise: load all static values ModBlocks.init(); ModEffects.init(); - LOGGER.info("Hello Fabric world!"); + ModEnchantments.registerModEnchantmentEffects(); + LOGGER.info("Thanks for trying out our stuff!"); } } \ No newline at end of file diff --git a/src/main/java/xyz/nearmisses/patience/mc_rebalance/MCRebalanceDataGen.java b/src/main/java/xyz/nearmisses/patience/mc_rebalance/MCRebalanceDataGen.java new file mode 100644 index 0000000..28a3878 --- /dev/null +++ b/src/main/java/xyz/nearmisses/patience/mc_rebalance/MCRebalanceDataGen.java @@ -0,0 +1,13 @@ +package xyz.nearmisses.patience.mc_rebalance; + +import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; +import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; + +// More to practice than for actual use. +public class MCRebalanceDataGen implements DataGeneratorEntrypoint { + @Override + public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { + FabricDataGenerator.Pack pack = fabricDataGenerator.createPack(); + pack.addProvider(EnchantGen::new); + } +} diff --git a/src/main/java/xyz/nearmisses/patience/mc_rebalance/ModEnchantments.java b/src/main/java/xyz/nearmisses/patience/mc_rebalance/ModEnchantments.java new file mode 100644 index 0000000..c38c522 --- /dev/null +++ b/src/main/java/xyz/nearmisses/patience/mc_rebalance/ModEnchantments.java @@ -0,0 +1,35 @@ +package xyz.nearmisses.patience.mc_rebalance; + +import com.mojang.serialization.MapCodec; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.effects.EnchantmentEntityEffect; +import xyz.nearmisses.patience.mc_rebalance.enchantment.effect.WindupEffect; + +// Copied off the Fabric wiki. I don't think I like this code. +public class ModEnchantments { + + public static final ResourceKey Windup = of("windup"); + public static MapCodec Effect_Windup = register("windup_effect", WindupEffect.CODEC); + + private static ResourceKey of(String path) { + ResourceLocation id = ResourceLocation.fromNamespaceAndPath(MCRebalance.MOD_ID, path); + return ResourceKey.create(Registries.ENCHANTMENT, id); + } + + private static MapCodec register(String id, MapCodec codec) { + return Registry.register( + BuiltInRegistries.ENCHANTMENT_ENTITY_EFFECT_TYPE, + ResourceLocation.fromNamespaceAndPath(MCRebalance.MOD_ID, id), + codec + ); + } + + public static void registerModEnchantmentEffects() { + MCRebalance.LOGGER.info("Registering EnchantmentEffects for " + MCRebalance.MOD_ID); + } +} diff --git a/src/main/java/xyz/nearmisses/patience/mc_rebalance/enchantment/effect/WindupEffect.java b/src/main/java/xyz/nearmisses/patience/mc_rebalance/enchantment/effect/WindupEffect.java new file mode 100644 index 0000000..3086230 --- /dev/null +++ b/src/main/java/xyz/nearmisses/patience/mc_rebalance/enchantment/effect/WindupEffect.java @@ -0,0 +1,32 @@ +package xyz.nearmisses.patience.mc_rebalance.enchantment.effect; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.enchantment.EnchantedItemInUse; +import net.minecraft.world.item.enchantment.LevelBasedValue; +import net.minecraft.world.item.enchantment.effects.EnchantmentEntityEffect; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.NotNull; + +public record WindupEffect(LevelBasedValue amount) implements EnchantmentEntityEffect { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> + instance.group( + LevelBasedValue.CODEC.fieldOf("amount").forGetter(WindupEffect::amount) + ).apply(instance, WindupEffect::new) + ); + + @Override + public void apply(ServerLevel world, int level, EnchantedItemInUse context, Entity target, Vec3 pos) { + if (context.owner() != null && context.owner() instanceof Player player) { + player.getCooldowns().addCooldown(context.itemStack().getItem(), (int)(20 / this.amount.calculate(level)) ); // Tick conversion + } + } + + @Override + public @NotNull MapCodec codec() { + return CODEC; + } +} diff --git a/src/main/java/xyz/nearmisses/patience/mc_rebalance/mixin/CreakingRework.java b/src/main/java/xyz/nearmisses/patience/mc_rebalance/mixin/CreakingRework.java index e0caa11..97e1e4d 100644 --- a/src/main/java/xyz/nearmisses/patience/mc_rebalance/mixin/CreakingRework.java +++ b/src/main/java/xyz/nearmisses/patience/mc_rebalance/mixin/CreakingRework.java @@ -25,7 +25,7 @@ public class CreakingRework extends Monster { private static void createAttributes(CallbackInfoReturnable cir) { cir.setReturnValue( Monster.createMonsterAttributes() .add(Attributes.MAX_HEALTH, 1.0) - .add(Attributes.MOVEMENT_SPEED, 0.6) + .add(Attributes.MOVEMENT_SPEED, 0.6) // Vanilla pathfinding causes enemies to 'overshoot' and backtrack on speeds ~0.8+. I don't know why that still happens. .add(Attributes.ATTACK_DAMAGE, 15.0) .add(Attributes.FOLLOW_RANGE, 38.0) .add(Attributes.STEP_HEIGHT, 2.1) // Step over big fences diff --git a/src/main/java/xyz/nearmisses/patience/mc_rebalance/mixin/DiggerItemHitCooldownsTweak.java b/src/main/java/xyz/nearmisses/patience/mc_rebalance/mixin/DiggerItemHitCooldownsTweak.java new file mode 100644 index 0000000..50cc614 --- /dev/null +++ b/src/main/java/xyz/nearmisses/patience/mc_rebalance/mixin/DiggerItemHitCooldownsTweak.java @@ -0,0 +1,21 @@ +package xyz.nearmisses.patience.mc_rebalance.mixin; + +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.DiggerItem; +import net.minecraft.world.item.ItemStack; +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; + +// Required for the Windup enchantment effect to work correctly. Why would this not happen by default? +@Mixin(DiggerItem.class) +public class DiggerItemHitCooldownsTweak { + @Inject(method = "hurtEnemy", at = @At("HEAD"), cancellable = true) + private static void hurtEnemy(ItemStack itemStack, LivingEntity owner, LivingEntity target, CallbackInfoReturnable cir){ + if(owner instanceof Player && ((Player)owner).getCooldowns().isOnCooldown(itemStack.getItem())){ + cir.setReturnValue(false); + } + } +} diff --git a/src/main/resources/assets/mc_rebalance/lang/en_us.json b/src/main/resources/assets/mc_rebalance/lang/en_us.json index 92e7f1c..cced2f4 100644 --- a/src/main/resources/assets/mc_rebalance/lang/en_us.json +++ b/src/main/resources/assets/mc_rebalance/lang/en_us.json @@ -14,5 +14,6 @@ "item.mc_rebalance.golden_paxel": "Golden Paxel", "item.mc_rebalance.diamond_paxel": "Diamond Paxel", "item.mc_rebalance.netherite_paxel": "Dendrite Paxel", - "effect.mc_rebalance.shattered": "Shattered" + "effect.mc_rebalance.shattered": "Shattered", + "enchantment.mc_rebalance.windup": "Windup" } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 2aa502e..b7b0bb4 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -23,7 +23,7 @@ "xyz.nearmisses.patience.mc_rebalance.MCRebalanceClient" ], "fabric-datagen": [ - "xyz.nearmisses.patience.mc_rebalance.MCRebalanceDataGenerator" + "xyz.nearmisses.patience.mc_rebalance.MCRebalanceDataGen" ] }, "mixins": [ diff --git a/src/main/resources/mc_rebalance.mixins.json b/src/main/resources/mc_rebalance.mixins.json index d7cd29f..f670aeb 100644 --- a/src/main/resources/mc_rebalance.mixins.json +++ b/src/main/resources/mc_rebalance.mixins.json @@ -6,6 +6,7 @@ "BlazeAIRework", "BlazeRework", "CreakingRework", + "DiggerItemHitCooldownsTweak", "ExperienceOrbRework", "WardenRework", "WitherSkeletonRework"