workflow
Some checks failed
Build Mod / build (push) Failing after 8m44s

This commit is contained in:
2026-01-08 21:30:19 -06:00
parent fd9cae3117
commit 6c6d7e7287
35 changed files with 266 additions and 938 deletions

View File

@@ -1,60 +1,12 @@
package dev.sillyangel.more_spear_enchantments;
import net.minecraft.resources.Identifier;
import net.minecraft.world.item.Item;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.config.ModConfigEvent;
import net.minecraftforge.registries.ForgeRegistries;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
// An example config class. This is not required, but it's a good idea to have one to keep your config organized.
// Demonstrates how to use Forge's config APIs
@Mod.EventBusSubscriber(modid = MoreSpearEnchantments.MODID, bus = Mod.EventBusSubscriber.Bus.MOD)
@Mod.EventBusSubscriber(modid = MoreSpearEnchantments.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public class Config {
private static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder();
private static final ForgeConfigSpec.BooleanValue LOG_DIRT_BLOCK = BUILDER
.comment("Whether to log the dirt block on common setup")
.define("logDirtBlock", true);
private static final ForgeConfigSpec.IntValue MAGIC_NUMBER = BUILDER
.comment("A magic number")
.defineInRange("magicNumber", 42, 0, Integer.MAX_VALUE);
public static final ForgeConfigSpec.ConfigValue<String> MAGIC_NUMBER_INTRODUCTION = BUILDER
.comment("What you want the introduction message to be for the magic number")
.define("magicNumberIntroduction", "The magic number is... ");
// a list of strings that are treated as resource locations for items
private static final ForgeConfigSpec.ConfigValue<List<? extends String>> ITEM_STRINGS = BUILDER
.comment("A list of items to log on common setup.")
.defineListAllowEmpty("items", List.of("minecraft:iron_ingot"), Config::validateItemName);
static final ForgeConfigSpec SPEC = BUILDER.build();
public static boolean logDirtBlock;
public static int magicNumber;
public static String magicNumberIntroduction;
public static Set<Item> items;
private static boolean validateItemName(final Object obj) {
return obj instanceof final String itemName && ForgeRegistries.ITEMS.containsKey(Identifier.tryParse(itemName));
}
@SubscribeEvent
static void onLoad(final ModConfigEvent event) {
logDirtBlock = LOG_DIRT_BLOCK.get();
magicNumber = MAGIC_NUMBER.get();
magicNumberIntroduction = MAGIC_NUMBER_INTRODUCTION.get();
// convert the list of strings into a set of items
items = ITEM_STRINGS.get().stream()
.map(itemName -> ForgeRegistries.ITEMS.getValue(Identifier.tryParse(itemName)))
.collect(Collectors.toSet());
}
}

View File

@@ -1,123 +1,31 @@
package dev.sillyangel.more_spear_enchantments;
import com.mojang.logging.LogUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.food.FoodProperties;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.CreativeModeTabs;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.material.MapColor;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.BuildCreativeModeTabContentsEvent;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import dev.sillyangel.more_spear_enchantments.enchantment.ModEnchantmentEffects;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import org.slf4j.Logger;
// The value here should match an entry in the META-INF/mods.toml file
@Mod(MoreSpearEnchantments.MODID)
@Mod(MoreSpearEnchantments.MOD_ID)
public final class MoreSpearEnchantments {
// Define mod id in a common place for everything to reference
public static final String MODID = "examplemod";
// Directly reference a slf4j logger
private static final Logger LOGGER = LogUtils.getLogger();
// Create a Deferred Register to hold Blocks which will all be registered under the "examplemod" namespace
public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);
// Create a Deferred Register to hold Items which will all be registered under the "examplemod" namespace
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID);
// Create a Deferred Register to hold CreativeModeTabs which will all be registered under the "examplemod" namespace
public static final DeferredRegister<CreativeModeTab> CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MODID);
// Creates a new Block with the id "examplemod:example_block", combining the namespace and path
public static final RegistryObject<Block> EXAMPLE_BLOCK = BLOCKS.register("example_block",
() -> new Block(BlockBehaviour.Properties.of()
.setId(BLOCKS.key("example_block"))
.mapColor(MapColor.STONE)
)
);
// Creates a new BlockItem with the id "examplemod:example_block", combining the namespace and path
public static final RegistryObject<Item> EXAMPLE_BLOCK_ITEM = ITEMS.register("example_block",
() -> new BlockItem(EXAMPLE_BLOCK.get(), new Item.Properties().setId(ITEMS.key("example_block")))
);
// Creates a new food item with the id "examplemod:example_id", nutrition 1 and saturation 2
public static final RegistryObject<Item> EXAMPLE_ITEM = ITEMS.register("example_item",
() -> new Item(new Item.Properties()
.setId(ITEMS.key("example_item"))
.food(new FoodProperties.Builder()
.alwaysEdible()
.nutrition(1)
.saturationModifier(2f)
.build()
)
)
);
// Creates a creative tab with the id "examplemod:example_tab" for the example item, that is placed after the combat tab
public static final RegistryObject<CreativeModeTab> EXAMPLE_TAB = CREATIVE_MODE_TABS.register("example_tab", () -> CreativeModeTab.builder()
.withTabsBefore(CreativeModeTabs.COMBAT)
.icon(() -> EXAMPLE_ITEM.get().getDefaultInstance())
.displayItems((parameters, output) -> {
output.accept(EXAMPLE_ITEM.get()); // Add the example item to the tab. For your own tabs, this method is preferred over the event
}).build());
public static final String MOD_ID = "more_spear_enchantments";
public static final Logger LOGGER = LogUtils.getLogger();
public MoreSpearEnchantments(FMLJavaModLoadingContext context) {
var modBusGroup = context.getModBusGroup();
// Register the commonSetup method for modloading
FMLCommonSetupEvent.getBus(modBusGroup).addListener(this::commonSetup);
// Register the Deferred Register to the mod event bus so blocks get registered
BLOCKS.register(modBusGroup);
// Register the Deferred Register to the mod event bus so items get registered
ITEMS.register(modBusGroup);
// Register the Deferred Register to the mod event bus so tabs get registered
CREATIVE_MODE_TABS.register(modBusGroup);
// Register the item to a creative tab
BuildCreativeModeTabContentsEvent.BUS.addListener(MoreSpearEnchantments::addCreative);
// Register our mod's ForgeConfigSpec so that Forge can create and load the config file for us
context.registerConfig(ModConfig.Type.COMMON, Config.SPEC);
ModEnchantmentEffects.ENCHANTMENT_ENTITY_EFFECTS.register(modBusGroup);
LOGGER.info("Registered {} enchantment effect types", ModEnchantmentEffects.ENCHANTMENT_ENTITY_EFFECTS.getEntries().size());
}
private void commonSetup(final FMLCommonSetupEvent event) {
// Some common setup code
LOGGER.info("HELLO FROM COMMON SETUP");
if (Config.logDirtBlock)
LOGGER.info("DIRT BLOCK >> {}", ForgeRegistries.BLOCKS.getKey(Blocks.DIRT));
LOGGER.info(Config.magicNumberIntroduction + Config.magicNumber);
Config.items.forEach((item) -> LOGGER.info("ITEM >> {}", item.toString()));
}
// Add the example block item to the building blocks tab
private static void addCreative(BuildCreativeModeTabContentsEvent event) {
if (event.getTabKey() == CreativeModeTabs.BUILDING_BLOCKS)
event.accept(EXAMPLE_BLOCK_ITEM);
}
// You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent
@Mod.EventBusSubscriber(modid = MODID, value = Dist.CLIENT)
public static class ClientModEvents {
@SubscribeEvent
public static void onClientSetup(FMLClientSetupEvent event) {
// Some client setup code
LOGGER.info("HELLO FROM CLIENT SETUP");
LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName());
}
LOGGER.info("Initializing More Spear Enchantments");
LOGGER.info("Enchantment effects registered:");
LOGGER.info(" - Lightning (Thundering enchantment)");
LOGGER.info(" - Poison (Poisoning enchantment)");
LOGGER.info(" - Withering (Withering enchantment)");
LOGGER.info(" - Crippling (Crippling enchantment)");
LOGGER.info("Check enchanting table or use '/enchant' command to apply them to tridents!");
}
}

View File

@@ -0,0 +1,26 @@
package dev.sillyangel.more_spear_enchantments.enchantment;
import com.mojang.serialization.MapCodec;
import dev.sillyangel.more_spear_enchantments.MoreSpearEnchantments;
import dev.sillyangel.more_spear_enchantments.enchantment.effect.*;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.item.enchantment.effects.EnchantmentEntityEffect;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.RegistryObject;
public class ModEnchantmentEffects {
// Deferred register for enchantment effect types
public static final DeferredRegister<MapCodec<? extends EnchantmentEntityEffect>> ENCHANTMENT_ENTITY_EFFECTS =
DeferredRegister.create(Registries.ENCHANTMENT_ENTITY_EFFECT_TYPE, MoreSpearEnchantments.MOD_ID);
// Register enchantment effect types
public static final RegistryObject<MapCodec<LightningEnchantmentEffect>> LIGHTNING_EFFECT =
ENCHANTMENT_ENTITY_EFFECTS.register("lightning", () -> LightningEnchantmentEffect.CODEC);
public static final RegistryObject<MapCodec<PoisonEnchantmentEffect>> POISON_EFFECT =
ENCHANTMENT_ENTITY_EFFECTS.register("poison", () -> PoisonEnchantmentEffect.CODEC);
public static final RegistryObject<MapCodec<WitheringEnchantmentEffect>> WITHERING_EFFECT =
ENCHANTMENT_ENTITY_EFFECTS.register("withering", () -> WitheringEnchantmentEffect.CODEC);
public static final RegistryObject<MapCodec<CripplingEnchantmentEffect>> CRIPPLING_EFFECT =
ENCHANTMENT_ENTITY_EFFECTS.register("crippling", () -> CripplingEnchantmentEffect.CODEC);
}

View File

@@ -0,0 +1,52 @@
package dev.sillyangel.more_spear_enchantments.enchantment.effect;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
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;
public record CripplingEnchantmentEffect(LevelBasedValue duration) implements EnchantmentEntityEffect {
public static final MapCodec<CripplingEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
LevelBasedValue.CODEC.fieldOf("duration").forGetter(CripplingEnchantmentEffect::duration)
).apply(instance, CripplingEnchantmentEffect::new)
);
@Override
public void apply(ServerLevel world, int level, EnchantedItemInUse context, Entity target, Vec3 pos) {
if (target instanceof LivingEntity victim) {
if (context.owner() != null && context.owner() instanceof Player player) {
int Duration = (int) (this.duration.calculate(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.addEffect(new MobEffectInstance(
MobEffects.SLOWNESS,
Duration,
slownessAmplifier,
false,
true
));
victim.addEffect(new MobEffectInstance(
MobEffects.WEAKNESS,
Duration,
weaknessAmplifier,
false,
true
));
}
}
}
@Override
public MapCodec<? extends EnchantmentEntityEffect> codec() {
return CODEC;
}
}

View File

@@ -0,0 +1,43 @@
package dev.sillyangel.more_spear_enchantments.enchantment.effect;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.EntitySpawnReason;
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;
public record LightningEnchantmentEffect(LevelBasedValue amount) implements EnchantmentEntityEffect {
public static final MapCodec<LightningEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
LevelBasedValue.CODEC.fieldOf("amount").forGetter(LightningEnchantmentEffect::amount)
).apply(instance, LightningEnchantmentEffect::new)
);
@Override
public void apply(ServerLevel world, int level, EnchantedItemInUse context, Entity target, Vec3 pos) {
if (target instanceof LivingEntity victim) {
if (context.owner() != null && context.owner() instanceof Player player) {
float numStrikes = this.amount.calculate(level);
for (float i = 0; i < numStrikes; i++) {
BlockPos position = victim.blockPosition();
EntityType.LIGHTNING_BOLT.spawn(world, position, EntitySpawnReason.TRIGGERED);
}
}
}
}
@Override
public MapCodec<? extends EnchantmentEntityEffect> codec() {
return CODEC;
}
}

View File

@@ -0,0 +1,45 @@
package dev.sillyangel.more_spear_enchantments.enchantment.effect;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
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;
public record PoisonEnchantmentEffect(LevelBasedValue duration) implements EnchantmentEntityEffect {
public static final MapCodec<PoisonEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
LevelBasedValue.CODEC.fieldOf("duration").forGetter(PoisonEnchantmentEffect::duration)
).apply(instance, PoisonEnchantmentEffect::new)
);
@Override
public void apply(ServerLevel world, int level, EnchantedItemInUse context, Entity target, Vec3 pos) {
if (target instanceof LivingEntity victim) {
if (context.owner() != null && context.owner() instanceof Player player) {
int poisonDuration = (int) (this.duration.calculate(level) * 40); // Convert to ticks
int poisonAmplifier = level - 2; // Level 1 = Poison 0, Level 2 = Poison I, Level 3 = Poison II
victim.addEffect(new MobEffectInstance(
MobEffects.POISON,
poisonDuration,
poisonAmplifier,
false,
true
));
}
}
}
@Override
public MapCodec<? extends EnchantmentEntityEffect> codec() {
return CODEC;
}
}

View File

@@ -0,0 +1,46 @@
package dev.sillyangel.more_spear_enchantments.enchantment.effect;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
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;
public record WitheringEnchantmentEffect(LevelBasedValue duration) implements EnchantmentEntityEffect {
public static final MapCodec<WitheringEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
LevelBasedValue.CODEC.fieldOf("duration").forGetter(WitheringEnchantmentEffect::duration)
).apply(instance, WitheringEnchantmentEffect::new)
);
@Override
public void apply(ServerLevel world, int level, EnchantedItemInUse context, Entity target, Vec3 pos) {
if (target instanceof LivingEntity victim) {
if (context.owner() != null && context.owner() instanceof Player player) {
int witherDuration = (int) (this.duration.calculate(level) * 40); // Convert to ticks
int witherAmplifier = level - 2; // Level 1 = Wither 0, Level 2 = Wither I, Level 3 = Wither II
victim.addEffect(new MobEffectInstance(
MobEffects.WITHER,
witherDuration,
witherAmplifier,
false,
true
));
}
}
}
@Override
public MapCodec<? extends EnchantmentEntityEffect> codec() {
return CODEC;
}
}