This commit is contained in:
2026-01-01 23:31:01 -06:00
parent c36cbcea0d
commit 23dfcdc369
49 changed files with 1631 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
package dev.sillyangel.more_spear_enchantments.fabric;
import dev.sillyangel.more_spear_enchantments.fabric.datagen.ModItemTagProvider;
import dev.sillyangel.more_spear_enchantments.fabric.enchantment.ModEnchantmentGenerator;
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
public class MoreSpearEnchantmentsDataGenerator implements DataGeneratorEntrypoint {
@Override
public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) {
FabricDataGenerator.Pack pack = fabricDataGenerator.createPack();
pack.addProvider(ModItemTagProvider::new);
pack.addProvider(ModEnchantmentGenerator::new);
}
}

View File

@@ -0,0 +1,13 @@
package dev.sillyangel.more_spear_enchantments.fabric;
import dev.sillyangel.more_spear_enchantments.MoreSpearEnchantments;
import net.fabricmc.api.ModInitializer;
public class MoreSpearEnchantmentsFabric implements ModInitializer {
@Override
public void onInitialize() {
// Run our common setup
MoreSpearEnchantments.init();
}
}

View File

@@ -0,0 +1,10 @@
package dev.sillyangel.more_spear_enchantments.fabric.client;
import net.fabricmc.api.ClientModInitializer;
public final class MoreSpearEnchantmentsFabricClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
// This entrypoint is suitable for setting up client-specific logic, such as rendering.
}
}

View File

@@ -0,0 +1,29 @@
package dev.sillyangel.more_spear_enchantments.fabric.datagen;
import dev.sillyangel.more_spear_enchantments.util.ModTags;
import dev.sillyangel.more_spear_enchantments.MoreSpearEnchantments;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
import net.minecraft.item.Items;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.tag.ItemTags;
import java.util.concurrent.CompletableFuture;
public class ModItemTagProvider extends FabricTagProvider.ItemTagProvider {
public ModItemTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> completableFuture) {
super(output, completableFuture);
}
@Override
protected void configure(RegistryWrapper.WrapperLookup wrapperLookup) {
valueLookupBuilder(ModTags.Items.SPEARS)
.add(Items.WOODEN_SPEAR)
.add(Items.STONE_SPEAR)
.add(Items.COPPER_SPEAR)
.add(Items.IRON_SPEAR)
.add(Items.GOLDEN_SPEAR)
.add(Items.DIAMOND_SPEAR)
.add(Items.NETHERITE_SPEAR);
}
}

View File

@@ -0,0 +1,39 @@
package dev.sillyangel.more_spear_enchantments.fabric.enchantment;
import com.mojang.serialization.MapCodec;
import dev.sillyangel.more_spear_enchantments.MoreSpearEnchantments;
import dev.sillyangel.more_spear_enchantments.enchantment.effect.*;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.effect.EnchantmentEntityEffect;
public class ModEnchantmentEffects {
public static final RegistryKey<Enchantment> THUNDERING = of("thundering");
public static final RegistryKey<Enchantment> WITHERING = of("withering");
public static final RegistryKey<Enchantment> POISONING = of("poisoning");
public static final RegistryKey<Enchantment> CRIPPLING = of("crippling");
private static RegistryKey<Enchantment> of(String path) {
Identifier id = Identifier.of(MoreSpearEnchantments.MOD_ID, path);
return RegistryKey.of(RegistryKeys.ENCHANTMENT, id);
}
private static <T extends EnchantmentEntityEffect> MapCodec<T> register(String id, MapCodec<T> codec) {
return Registry.register(Registries.ENCHANTMENT_ENTITY_EFFECT_TYPE, Identifier.of(MoreSpearEnchantments.MOD_ID, id), codec);
}
public static void registerModEnchantmentEffects() {
MoreSpearEnchantments.LOGGER.info("Registering EnchantmentEffects for " + MoreSpearEnchantments.MOD_ID);
register("lightning", LightningEnchantmentEffect.CODEC);
register("poison", PoisonEnchantmentEffect.CODEC);
register("withering", WitheringEnchantmentEffect.CODEC);
register("crippling", CripplingEnchantmentEffect.CODEC);
}
}

View File

@@ -0,0 +1,120 @@
package dev.sillyangel.more_spear_enchantments.fabric.enchantment;
import dev.sillyangel.more_spear_enchantments.util.ModTags;
import dev.sillyangel.more_spear_enchantments.enchantment.effect.*;
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.registry.RegistryWrapper;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryKey;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.effect.EnchantmentEffectTarget;
import net.minecraft.enchantment.EnchantmentLevelBasedValue;
import net.minecraft.component.type.AttributeModifierSlot;
import net.minecraft.component.EnchantmentEffectComponentTypes;
import java.util.concurrent.CompletableFuture;
public class ModEnchantmentGenerator extends FabricDynamicRegistryProvider {
public ModEnchantmentGenerator(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
super(output, registriesFuture);
System.out.println("REGISTERING ENCHANTS");
}
@Override
protected void configure(RegistryWrapper.WrapperLookup registries, Entries entries) {
// Our new enchantment, "Thundering."
register(entries, ModEnchantmentEffects.THUNDERING, Enchantment.builder(
Enchantment.definition(
registries.getOrThrow(RegistryKeys.ITEM).getOrThrow(ModTags.Items.SPEARS),
// this is the "weight" or probability of our enchantment showing up in the table
10,
// the maximum level of the enchantment
3,
// base cost for level 1 of the enchantment, and min levels required for something higher
Enchantment.leveledCost(1, 10),
// same fields as above but for max cost
Enchantment.leveledCost(1, 15),
// anvil cost
5,
// valid slots
AttributeModifierSlot.HAND
)
)
.addEffect(
// enchantment occurs POST_ATTACK
EnchantmentEffectComponentTypes.POST_ATTACK,
EnchantmentEffectTarget.ATTACKER,
EnchantmentEffectTarget.VICTIM,
new LightningEnchantmentEffect(EnchantmentLevelBasedValue.linear(0.4f, 0.2f)) // scale the enchantment linearly.
)
);
register(entries, ModEnchantmentEffects.POISONING, Enchantment.builder(
Enchantment.definition(
registries.getOrThrow(RegistryKeys.ITEM).getOrThrow(ModTags.Items.SPEARS),
10,
3,
Enchantment.leveledCost(1, 10),
Enchantment.leveledCost(1, 15),
5,
AttributeModifierSlot.HAND
)
)
.addEffect(
EnchantmentEffectComponentTypes.POST_ATTACK,
EnchantmentEffectTarget.ATTACKER,
EnchantmentEffectTarget.VICTIM,
new PoisonEnchantmentEffect(EnchantmentLevelBasedValue.linear(3.0f, 1.0f)) // 3s base, +1s per level
)
);
// Our new enchantment, "Withering."
register(entries, ModEnchantmentEffects.WITHERING, Enchantment.builder(
Enchantment.definition(
registries.getOrThrow(RegistryKeys.ITEM).getOrThrow(ModTags.Items.SPEARS),
10,
3,
Enchantment.leveledCost(1, 10),
Enchantment.leveledCost(1, 15),
5,
AttributeModifierSlot.HAND
)
)
.addEffect(
EnchantmentEffectComponentTypes.POST_ATTACK,
EnchantmentEffectTarget.ATTACKER,
EnchantmentEffectTarget.VICTIM,
new WitheringEnchantmentEffect(EnchantmentLevelBasedValue.linear(2.0f, 1.0f)) // 2s base, +1s per level
)
);
// Our new enchantment, "Crippling."
register(entries, ModEnchantmentEffects.CRIPPLING, Enchantment.builder(
Enchantment.definition(
registries.getOrThrow(RegistryKeys.ITEM).getOrThrow(ModTags.Items.SPEARS),
10,
3,
Enchantment.leveledCost(1, 10),
Enchantment.leveledCost(1, 15),
5,
AttributeModifierSlot.HAND
)
)
.addEffect(
EnchantmentEffectComponentTypes.POST_ATTACK,
EnchantmentEffectTarget.ATTACKER,
EnchantmentEffectTarget.VICTIM,
new CripplingEnchantmentEffect(EnchantmentLevelBasedValue.linear(2.0f, 1.0f)) // 2s base, +1s per leve
)
);
}
private void register(Entries entries, RegistryKey<Enchantment> key, Enchantment.Builder builder, ResourceCondition... resourceConditions) {
entries.add(key, builder.build(key.getValue()), resourceConditions);
}
@Override
public String getName() {
return "ModEnchantmentGenerator";
}
}

View File

@@ -0,0 +1,52 @@
package dev.sillyangel.more_spear_enchantments.fabric.enchantment.effect;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.enchantment.EnchantmentEffectContext;
import net.minecraft.enchantment.EnchantmentLevelBasedValue;
import net.minecraft.enchantment.effect.EnchantmentEntityEffect;
import net.minecraft.util.math.Vec3d;
public record CripplingEnchantmentEffect(EnchantmentLevelBasedValue duration) implements EnchantmentEntityEffect {
public static final MapCodec<CripplingEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
EnchantmentLevelBasedValue.CODEC.fieldOf("duration").forGetter(CripplingEnchantmentEffect::duration)
).apply(instance, CripplingEnchantmentEffect::new)
);
@Override
public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
if (target instanceof LivingEntity victim) {
if (context.owner() != null && context.owner() instanceof PlayerEntity player) {
int Duration = (int) (this.duration.getValue(level) * 50); // Convert to ticks
int slownessAmplifier = level - 1; // Level 1 = Slowness 0, Level 2 = Slowness I, Level 3 = Slowness II
int weaknessAmplifier = level - 1; // Level 1 = Weakness 0, Level 2 = Weakness I, Level 3 = Weakness II
victim.addStatusEffect(new StatusEffectInstance(
StatusEffects.SLOWNESS,
Duration,
slownessAmplifier,
false,
true
));
victim.addStatusEffect(new StatusEffectInstance(
StatusEffects.WEAKNESS,
Duration,
weaknessAmplifier,
false,
true
));
}
}
}
@Override
public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
return CODEC;
}
}

View File

@@ -0,0 +1,43 @@
package dev.sillyangel.more_spear_enchantments.fabric.enchantment.effect;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.util.math.BlockPos;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.enchantment.EnchantmentEffectContext;
import net.minecraft.enchantment.EnchantmentLevelBasedValue;
import net.minecraft.enchantment.effect.EnchantmentEntityEffect;
import net.minecraft.util.math.Vec3d;
public record LightningEnchantmentEffect(EnchantmentLevelBasedValue amount) implements EnchantmentEntityEffect {
public static final MapCodec<LightningEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
EnchantmentLevelBasedValue.CODEC.fieldOf("amount").forGetter(LightningEnchantmentEffect::amount)
).apply(instance, LightningEnchantmentEffect::new)
);
@Override
public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
if (target instanceof LivingEntity victim) {
if (context.owner() != null && context.owner() instanceof PlayerEntity player) {
float numStrikes = this.amount.getValue(level);
for (float i = 0; i < numStrikes; i++) {
BlockPos position = victim.getBlockPos();
EntityType.LIGHTNING_BOLT.spawn(world, position, SpawnReason.TRIGGERED);
}
}
}
}
@Override
public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
return CODEC;
}
}

View File

@@ -0,0 +1,45 @@
package dev.sillyangel.more_spear_enchantments.fabric.enchantment.effect;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.enchantment.EnchantmentEffectContext;
import net.minecraft.enchantment.EnchantmentLevelBasedValue;
import net.minecraft.enchantment.effect.EnchantmentEntityEffect;
import net.minecraft.util.math.Vec3d;
public record PoisonEnchantmentEffect(EnchantmentLevelBasedValue duration) implements EnchantmentEntityEffect {
public static final MapCodec<PoisonEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
EnchantmentLevelBasedValue.CODEC.fieldOf("duration").forGetter(PoisonEnchantmentEffect::duration)
).apply(instance, PoisonEnchantmentEffect::new)
);
@Override
public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
if (target instanceof LivingEntity victim) {
if (context.owner() != null && context.owner() instanceof PlayerEntity player) {
int poisonDuration = (int) (this.duration.getValue(level) * 40); // Convert to ticks
int poisonAmplifier = level - 2; // Level 1 = Poison 0, Level 2 = Poison I, Level 3 = Poison II
victim.addStatusEffect(new StatusEffectInstance(
StatusEffects.POISON,
poisonDuration,
poisonAmplifier,
false,
true
));
}
}
}
@Override
public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
return CODEC;
}
}

View File

@@ -0,0 +1,46 @@
package dev.sillyangel.more_spear_enchantments.fabric.enchantment.effect;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.enchantment.EnchantmentEffectContext;
import net.minecraft.enchantment.EnchantmentLevelBasedValue;
import net.minecraft.enchantment.effect.EnchantmentEntityEffect;
import net.minecraft.util.math.Vec3d;
public record WitheringEnchantmentEffect(EnchantmentLevelBasedValue duration) implements EnchantmentEntityEffect {
public static final MapCodec<WitheringEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
EnchantmentLevelBasedValue.CODEC.fieldOf("duration").forGetter(WitheringEnchantmentEffect::duration)
).apply(instance, WitheringEnchantmentEffect::new)
);
@Override
public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
if (target instanceof LivingEntity victim) {
if (context.owner() != null && context.owner() instanceof PlayerEntity player) {
int witherDuration = (int) (this.duration.getValue(level) * 40); // Convert to ticks
int witherAmplifier = level - 2; // Level 1 = Wither 0, Level 2 = Wither I, Level 3 = Wither II
victim.addStatusEffect(new StatusEffectInstance(
StatusEffects.WITHER,
witherDuration,
witherAmplifier,
false,
true
));
}
}
}
@Override
public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
return CODEC;
}
}

View File

@@ -0,0 +1,15 @@
package dev.sillyangel.more_spear_enchantments.fabric.mixin;
import net.minecraft.server.MinecraftServer;
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.CallbackInfo;
@Mixin(MinecraftServer.class)
public class ExampleMixin {
@Inject(at = @At("HEAD"), method = "loadWorld")
private void init(CallbackInfo info) {
// This code is injected into the start of MinecraftServer.loadWorld()V
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -0,0 +1,46 @@
{
"schemaVersion": 1,
"id": "more_spear_enchantments",
"version": "${version}",
"name": "More Spear Enchantments",
"description": "more enchantments for the newly added spear from the Mounts of Mayhem update.",
"authors": [
"sillyangel"
],
"contact": {
"homepage": "https://sillyangel.dev/",
"sources": "https://git.sillyangel.dev/angel/more-spear-enchants"
},
"license": "MIT",
"icon": "assets/more_spear_enchantments/icon.png",
"environment": "*",
"entrypoints": {
"main": [
"dev.sillyangel.more_spear_enchantments.fabric.MoreSpearEnchantmentsFabric"
],
"client": [
"dev.sillyangel.more_spear_enchantments.fabric.client.MoreSpearEnchantmentsFabricClient"
],
"fabric-datagen": [
"dev.sillyangel.more_spear_enchantments.fabric.MoreSpearEnchantmentsDataGenerator"
]
},
"mixins": [
"more_spear_enchantments.mixins.json"
],
"depends": {
"fabricloader": ">=0.18.3",
"minecraft": "~1.21.11",
"java": ">=21",
"architectury": ">=19.0.1",
"fabric-api": "*"
},
"custom": {
"modmenu": {
"links": {
"modmenu.discord": "https://discord.gg/gAfcZURgvJ"
},
"update_checker": true
}
}
}