Compare commits

...

6 commits

Author SHA1 Message Date
Ell 16582e6d25 40.0 2024-03-12 20:12:46 +01:00
Ell 2b0dc58438 resolved todo 2024-03-12 20:10:30 +01:00
Ell fc6c376d37 fixed recipes 2024-03-12 20:09:56 +01:00
Ell 5497de1f1d fixed up some issues 2024-03-12 19:53:57 +01:00
Ell b3bc24ef09 generate data 2024-03-12 19:13:58 +01:00
Ell f7f425d7c8 IT COMPILES??? 2024-03-12 19:04:56 +01:00
51 changed files with 260 additions and 369 deletions

1
.gitignore vendored
View file

@ -14,6 +14,7 @@
/run/
/run-data/
/logs
/runs
*.classpath
*.project

View file

@ -13,7 +13,7 @@ minecraft_version=1.20.4
# as they do not follow standard versioning conventions.
minecraft_version_range=[1.20.4,1.21)
# The Neo version must agree with the Minecraft version to get a valid artifact
neo_version=20.4.80-beta
neo_version=20.4.198
# The Neo version range can use any version of Neo as bounds
neo_version_range=[20.4,)
# The loader version range can only use the major version of FML as bounds
@ -32,7 +32,7 @@ mod_name=NaturesAura
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=MIT
# The mod version. See https://semver.org/
mod_version=39.4
mod_version=40.0
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html

View file

@ -0,0 +1 @@
{}

View file

@ -0,0 +1 @@
{}

View file

@ -0,0 +1 @@
{}

View file

@ -1,5 +1,5 @@
{
"type": "forge:add_features",
"type": "neoforge:add_features",
"biomes": "#minecraft:is_overworld",
"features": "naturesaura:aura_bloom",
"step": "vegetal_decoration"

View file

@ -1,5 +1,5 @@
{
"type": "forge:add_features",
"type": "neoforge:add_features",
"biomes": "#forge:is_sandy",
"features": "naturesaura:aura_cactus",
"step": "vegetal_decoration"

View file

@ -1,5 +1,5 @@
{
"type": "forge:add_features",
"type": "neoforge:add_features",
"biomes": "#forge:is_mushroom",
"features": "naturesaura:aura_mushroom",
"step": "vegetal_decoration"

View file

@ -1,5 +1,5 @@
{
"type": "forge:add_features",
"type": "neoforge:add_features",
"biomes": "#minecraft:is_nether",
"features": "naturesaura:crimson_aura_mushroom",
"step": "vegetal_decoration"

View file

@ -1,5 +1,5 @@
{
"type": "forge:add_features",
"type": "neoforge:add_features",
"biomes": "#minecraft:is_nether",
"features": "naturesaura:warped_aura_mushroom",
"step": "vegetal_decoration"

View file

@ -1,7 +1,6 @@
package de.ellpeck.naturesaura;
import com.mojang.blaze3d.vertex.VertexConsumer;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.container.IAuraContainer;
import de.ellpeck.naturesaura.api.aura.item.IAuraRecharge;
import de.ellpeck.naturesaura.api.misc.ILevelData;
@ -14,7 +13,6 @@ import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
@ -45,13 +43,12 @@ import net.minecraft.world.phys.Vec3;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.capabilities.ICapabilityProvider;
import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.items.IItemHandlerModifiable;
import top.theillusivec4.curios.api.CuriosApi;
import top.theillusivec4.curios.api.SlotResult;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Locale;
@ -119,7 +116,6 @@ public final class Helper {
}
public static boolean areItemsEqual(ItemStack first, ItemStack second, boolean nbt) {
// TODO see if this is the correct new comparison method?
return nbt ? ItemStack.isSameItemSameTags(first, second) : ItemStack.isSameItem(first, second);
}
@ -200,21 +196,11 @@ public final class Helper {
return InteractionResult.CONSUME;
}
public static ICapabilityProvider makeRechargeProvider(ItemStack stack, boolean needsSelected) {
return new ICapabilityProvider() {
private final LazyOptional<IAuraRecharge> recharge = LazyOptional.of(() -> (container, containerSlot, itemSlot, isSelected) -> {
if (isSelected || !needsSelected)
return Helper.rechargeAuraItem(stack, container, 300);
return false;
});
@Nullable
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable Direction facing) {
if (capability == NaturesAuraAPI.CAP_AURA_RECHARGE)
return this.recharge.cast();
return LazyOptional.empty();
}
public static ICapabilityProvider<ItemStack, Void, IAuraRecharge> makeRechargeProvider(boolean needsSelected) {
return (stack, ctx) -> (container, containerSlot, itemSlot, isSelected) -> {
if (isSelected || !needsSelected)
return Helper.rechargeAuraItem(stack, container, 300);
return false;
};
}
@ -313,9 +299,12 @@ public final class Helper {
public static ItemStack getEquippedItem(Predicate<ItemStack> predicate, Player player, boolean hotbarOnly) {
if (Compat.hasCompat("curios")) {
var stack = CuriosApi.getCuriosHelper().findFirstCurio(player, predicate).map(SlotResult::stack);
if (stack.isPresent())
return stack.get();
var inventory = CuriosApi.getCuriosInventory(player);
if (inventory.isPresent()) {
var stack = inventory.get().findFirstCurio(predicate).map(SlotResult::stack);
if (stack.isPresent())
return stack.get();
}
}
var invSize = hotbarOnly ? 9 : player.getInventory().getContainerSize();
for (var i = 0; i < invSize; i++) {

View file

@ -13,6 +13,7 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Tuple;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.apache.commons.lang3.mutable.MutableFloat;
@ -201,8 +202,8 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
}
@Override
public IAuraChunk createAuraChunk() {
return new AuraChunk();
public IAuraChunk createAuraChunk(LevelChunk chunk) {
return new AuraChunk(chunk);
}
}

View file

@ -2,7 +2,6 @@ package de.ellpeck.naturesaura.api;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import de.ellpeck.naturesaura.api.aura.chunk.AuraChunkProvider;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.container.IAuraContainer;
@ -23,6 +22,7 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.attachment.AttachmentType;
@ -99,7 +99,7 @@ public final class NaturesAuraAPI {
/**
* The capability that any chunk in a level has to store Aura in it. As this is only applicable to chunks and all chunks in the level automatically get assigned this capability, using it directly is not necessary for addon developers. To retrieve this capability from any chunk, use the helper method {@link IAuraChunk#getAuraChunk(net.minecraft.world.level.Level, BlockPos)}.
*/
public static final AttachmentType<AuraChunkProvider> AURA_CHUNK_ATTACHMENT = AttachmentType.serializable(AuraChunkProvider::new).build();
public static final AttachmentType<IAuraChunk> AURA_CHUNK_ATTACHMENT = AttachmentType.serializable(h -> NaturesAuraAPI.instance().createAuraChunk((LevelChunk) h)).build();
private static final IInternalHooks INSTANCE;
static {
@ -260,7 +260,7 @@ public final class NaturesAuraAPI {
ILevelData getLevelData(Level level);
IAuraChunk createAuraChunk();
IAuraChunk createAuraChunk(LevelChunk chunk);
}

View file

@ -1,29 +0,0 @@
package de.ellpeck.naturesaura.api.aura.chunk;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.chunk.LevelChunk;
import net.neoforged.neoforge.common.util.INBTSerializable;
public class AuraChunkProvider implements INBTSerializable<CompoundTag> {
private IAuraChunk auraChunk;
public IAuraChunk get(LevelChunk chunk) {
if (this.auraChunk == null)
this.auraChunk = NaturesAuraAPI.instance().createAuraChunk();
this.auraChunk.ensureInitialized(chunk);
return this.auraChunk;
}
@Override
public CompoundTag serializeNBT() {
return this.get(null).serializeNBT();
}
@Override
public void deserializeNBT(CompoundTag nbt) {
this.get(null).deserializeNBT(nbt);
}
}

View file

@ -33,7 +33,7 @@ public interface IAuraChunk extends INBTSerializable<CompoundTag> {
*/
static IAuraChunk getAuraChunk(Level level, BlockPos pos) {
var chunk = (LevelChunk) level.getChunk(pos);
return chunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT).get(chunk);
return chunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT);
}
/**
@ -160,6 +160,4 @@ public interface IAuraChunk extends INBTSerializable<CompoundTag> {
void markDirty();
void ensureInitialized(LevelChunk chunk);
}

View file

@ -50,7 +50,7 @@ public class BlockProjectileGenerator extends BlockContainerImpl implements ITES
protected Projectile getProjectile(Level levelIn, Position position, ItemStack stackIn) {
var ret = new ThrownTrident(EntityType.TRIDENT, levelIn);
ret.setPos(position.x(), position.y(), position.z());
ObfuscationReflectionHelper.setPrivateValue(ThrownTrident.class, ret, stackIn.copy(), "f_37555_");
ObfuscationReflectionHelper.setPrivateValue(ThrownTrident.class, ret, stackIn.copy(), "pickupItemStack");
ret.pickup = AbstractArrow.Pickup.ALLOWED;
return ret;
}

View file

@ -24,13 +24,12 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.level.SaplingGrowTreeEvent;
import net.neoforged.bus.api.SubscribeEvent;
import org.apache.commons.lang3.mutable.MutableObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BlockWoodStand extends BlockContainerImpl implements ITESRProvider<BlockEntityWoodStand>, ICustomBlockState {
@ -89,7 +88,7 @@ public class BlockWoodStand extends BlockContainerImpl implements ITESRProvider<
});
if (fine && required.isEmpty()) {
toPick.getValue().setRitual(pos, recipe.value());
toPick.getValue().setRitual(pos, recipe);
break;
}
}

View file

@ -24,7 +24,7 @@ import java.lang.reflect.Field;
public class BlockEntityFurnaceHeater extends BlockEntityImpl implements ITickableBlockEntity {
private static final Field FURNACE_DATA_FIELD = ObfuscationReflectionHelper.findField(AbstractFurnaceBlockEntity.class, "f_58311_");
private static final Field FURNACE_DATA_FIELD = ObfuscationReflectionHelper.findField(AbstractFurnaceBlockEntity.class, "dataAccess");
public boolean isActive;
public BlockEntityFurnaceHeater(BlockPos pos, BlockState state) {

View file

@ -83,7 +83,7 @@ public class BlockEntityWoodStand extends BlockEntityImpl implements ITickableBl
var item = new ItemEntity(this.level,
this.ritualPos.getX() + 0.5, this.ritualPos.getY() + 4.5, this.ritualPos.getZ() + 0.5,
this.recipe.value().result.copy());
this.recipe.value().output.copy());
this.level.addFreshEntity(item);
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32,

View file

@ -16,6 +16,7 @@ import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.neoforge.capabilities.Capabilities;
public class RenderAuraTimer implements BlockEntityRenderer<BlockEntityAuraTimer> {
@ -27,7 +28,7 @@ public class RenderAuraTimer implements BlockEntityRenderer<BlockEntityAuraTimer
@Override
public void render(BlockEntityAuraTimer tile, float partialTicks, PoseStack stack, MultiBufferSource buffer, int combinedLightIn, int combinedOverlayIn) {
var bottle = tile.getItemHandler().getStackInSlot(0);
var bottle = tile.getLevel().getCapability(Capabilities.ItemHandler.BLOCK, tile.getBlockPos(), tile.getBlockState(), tile, null).getStackInSlot(0);
if (bottle.isEmpty())
return;
stack.pushPose();
@ -61,5 +62,7 @@ public class RenderAuraTimer implements BlockEntityRenderer<BlockEntityAuraTimer
public void renderToBuffer(PoseStack matrixStackIn, VertexConsumer bufferIn, int packedLightIn, int packedOverlayIn, float red, float green, float blue, float alpha) {
this.model.render(matrixStackIn, bufferIn, packedLightIn, packedOverlayIn, red, green, blue, alpha);
}
}
}

View file

@ -37,17 +37,12 @@ public class AuraChunk implements IAuraChunk {
private final Table<BlockPos, Integer, Pair<Integer, Integer>> auraAndSpotAmountCache = HashBasedTable.create();
private final Table<BlockPos, Integer, Pair<BlockPos, Integer>[]> limitSpotCache = HashBasedTable.create();
private final List<IDrainSpotEffect> effects = new ArrayList<>();
private final LevelChunk chunk;
private final IAuraType type;
private LevelChunk chunk;
private IAuraType type;
private boolean needsSync;
@Override
public void ensureInitialized(LevelChunk chunk) {
// are we already initialized?
if (this.chunk != null)
return;
public AuraChunk(LevelChunk chunk) {
this.chunk = chunk;
this.type = IAuraType.forLevel(chunk.getLevel());

View file

@ -6,6 +6,8 @@ import de.ellpeck.naturesaura.compat.patchouli.PatchouliCompat;
import de.ellpeck.naturesaura.data.ItemTagProvider;
import net.neoforged.fml.ModList;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
import net.neoforged.neoforge.data.event.GatherDataEvent;
import java.util.HashMap;
import java.util.Map;
@ -34,12 +36,20 @@ public final class Compat {
return Compat.MODULES.containsKey(mod);
}
public static void addItemTags(ItemTagProvider provider) {
public static void gatherData(GatherDataEvent event) {
// since other mods don't get loaded in runData, just populate all modules
Compat.populateModules(s -> true);
Compat.MODULES.values().forEach(m -> m.gatherData(event));
}
public static void addItemTags(ItemTagProvider provider) {
Compat.MODULES.values().forEach(m -> m.addItemTags(provider));
}
public static void addCapabilities(RegisterCapabilitiesEvent event) {
Compat.MODULES.values().forEach(c -> c.addCapabilities(event));
}
private static void populateModules(Predicate<String> isLoaded) {
for (var entry : Compat.MODULE_TYPES.entrySet()) {
var id = entry.getKey();
@ -49,4 +59,5 @@ public final class Compat {
}
}
}
}

View file

@ -4,28 +4,22 @@ import com.google.common.collect.ImmutableMap;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.data.ItemTagProvider;
import de.ellpeck.naturesaura.items.ModItems;
import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup;
import net.minecraft.data.PackOutput;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.ItemTags;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.common.capabilities.Capability;
import net.neoforged.fml.InterModComms;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.fml.event.lifecycle.InterModEnqueueEvent;
import net.neoforged.fml.javafmlmod.FMLJavaModLoadingContext;
import net.neoforged.neoforge.common.capabilities.ICapabilityProvider;
import net.neoforged.neoforge.common.util.LazyOptional;
import net.neoforged.neoforge.event.AttachCapabilitiesEvent;
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
import net.neoforged.neoforge.common.data.ExistingFileHelper;
import net.neoforged.neoforge.data.event.GatherDataEvent;
import top.theillusivec4.curios.api.CuriosCapability;
import top.theillusivec4.curios.api.CuriosDataProvider;
import top.theillusivec4.curios.api.SlotContext;
import top.theillusivec4.curios.api.SlotTypeMessage;
import top.theillusivec4.curios.api.type.capability.ICurio;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
public class CuriosCompat implements ICompat {
@ -39,55 +33,35 @@ public class CuriosCompat implements ICompat {
.build();
@Override
public void setup(FMLCommonSetupEvent event) {
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::sendImc);
NeoForge.EVENT_BUS.addGenericListener(ItemStack.class, this::onCapabilitiesAttach);
public void addCapabilities(RegisterCapabilitiesEvent event) {
for (var item : CuriosCompat.TYPES.keySet()) {
event.registerItem(CuriosCapability.ITEM, (s, c) -> new ICurio() {
@Override
public void curioTick(SlotContext slotContext) {
s.getItem().inventoryTick(s, slotContext.entity().level(), slotContext.entity(), -1, false);
}
@Override
public ItemStack getStack() {
return s;
}
@Override
public boolean canEquipFromUse(SlotContext slotContext) {
return true;
}
@Override
public boolean canSync(SlotContext slotContext) {
return true;
}
}, item);
}
}
@Override
public void setupClient() {
}
private void sendImc(InterModEnqueueEvent event) {
CuriosCompat.TYPES.values().stream().distinct().forEach(t -> InterModComms.sendTo("curios", SlotTypeMessage.REGISTER_TYPE, () -> new SlotTypeMessage.Builder(t).build()));
}
private void onCapabilitiesAttach(AttachCapabilitiesEvent<ItemStack> event) {
var stack = event.getObject();
if (CuriosCompat.TYPES.containsKey(stack.getItem())) {
event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "curios"), new ICapabilityProvider() {
private final LazyOptional<ICurio> curio = LazyOptional.of(() -> new ICurio() {
@Override
public void curioTick(SlotContext slotContext) {
stack.getItem().inventoryTick(stack, slotContext.entity().level(), slotContext.entity(), -1, false);
}
@Override
public ItemStack getStack() {
return stack;
}
@Override
public boolean canEquipFromUse(SlotContext slotContext) {
return true;
}
@Override
public boolean canSync(SlotContext slotContext) {
return true;
}
});
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
if (cap != CuriosCapability.ITEM)
return LazyOptional.empty();
return this.curio.cast();
}
});
}
public void gatherData(GatherDataEvent event) {
event.getGenerator().addProvider(event.includeServer(), new CuriosProvider(event.getGenerator().getPackOutput(), event.getExistingFileHelper(), event.getLookupProvider()));
}
@Override
@ -97,4 +71,20 @@ public class CuriosCompat implements ICompat {
provider.tag(tag).add(entry.getKey());
}
}
private static class CuriosProvider extends CuriosDataProvider {
public CuriosProvider(PackOutput output, ExistingFileHelper fileHelper, CompletableFuture<HolderLookup.Provider> registries) {
super(NaturesAura.MOD_ID, output, fileHelper, registries);
}
@Override
public void generate(HolderLookup.Provider provider, ExistingFileHelper existingFileHelper) {
for (var type : CuriosCompat.TYPES.values()) {
this.createSlot(type);
}
}
}
}

View file

@ -2,12 +2,19 @@ package de.ellpeck.naturesaura.compat;
import de.ellpeck.naturesaura.data.ItemTagProvider;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
import net.neoforged.neoforge.data.event.GatherDataEvent;
public interface ICompat {
void setup(FMLCommonSetupEvent event);
default void setup(FMLCommonSetupEvent event) {}
void setupClient();
default void setupClient() {}
default void gatherData(GatherDataEvent event) {}
default void addItemTags(ItemTagProvider provider) {}
default void addCapabilities(RegisterCapabilitiesEvent event) {}
void addItemTags(ItemTagProvider provider);
}

View file

@ -45,7 +45,7 @@ public class TreeRitualCategory implements IRecipeCategory<TreeRitualRecipe> {
@Override
public void setRecipe(IRecipeLayoutBuilder builder, TreeRitualRecipe recipe, IFocusGroup focuses) {
builder.addSlot(RecipeIngredientRole.CATALYST, 35, 35).addItemStacks(Arrays.asList(recipe.saplingType.getItems()));
builder.addSlot(RecipeIngredientRole.OUTPUT, 125, 35).addItemStack(recipe.result);
builder.addSlot(RecipeIngredientRole.OUTPUT, 125, 35).addItemStack(recipe.output);
var positions = new int[][]{{35, 1}, {35, 69}, {1, 35}, {69, 35}, {12, 12}, {58, 58}, {58, 12}, {12, 58}};
for (var i = 0; i < recipe.ingredients.size(); i++)

View file

@ -24,9 +24,9 @@ public class ProcessorTreeRitual implements IComponentProcessor {
return this.recipe.ingredients.size() > id ? PatchouliCompat.ingredientVariable(this.recipe.ingredients.get(id)) : null;
} else {
return switch (key) {
case "output" -> IVariable.from(this.recipe.result);
case "output" -> IVariable.from(this.recipe.output);
case "sapling" -> PatchouliCompat.ingredientVariable(this.recipe.saplingType);
case "name" -> IVariable.wrap(this.recipe.result.getHoverName().getString());
case "name" -> IVariable.wrap(this.recipe.output.getHoverName().getString());
default -> null;
};
}

View file

@ -1,8 +1,9 @@
package de.ellpeck.naturesaura.data;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.compat.Compat;
import de.ellpeck.naturesaura.gen.ModFeatures;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.Cloner;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.RegistrySetBuilder;
import net.minecraft.core.registries.BuiltInRegistries;
@ -10,10 +11,11 @@ import net.minecraft.core.registries.Registries;
import net.minecraft.data.loot.LootTableProvider;
import net.minecraft.data.registries.VanillaRegistries;
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import net.neoforged.neoforge.common.data.DatapackBuiltinEntriesProvider;
import net.neoforged.neoforge.data.event.GatherDataEvent;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.common.data.DatapackBuiltinEntriesProvider;
import net.neoforged.neoforge.data.event.GatherDataEvent;
import net.neoforged.neoforge.registries.DataPackRegistriesHooks;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
import java.util.List;
@ -30,6 +32,8 @@ public final class ModData {
var lookup = event.getLookupProvider();
var existing = event.getExistingFileHelper();
Compat.gatherData(event);
var blockTags = new BlockTagProvider(out, lookup, existing);
gen.addProvider(event.includeServer(), blockTags);
gen.addProvider(event.includeServer(), new ItemTagProvider(out, lookup, blockTags.contentsGetter(), existing));
@ -39,16 +43,18 @@ public final class ModData {
gen.addProvider(event.includeServer(), new DatapackBuiltinEntriesProvider(out, CompletableFuture.supplyAsync(ModData::getProvider), Set.of(NaturesAura.MOD_ID)));
}
private static HolderLookup.Provider getProvider() {
final RegistrySetBuilder registryBuilder = new RegistrySetBuilder();
@SuppressWarnings("UnstableApiUsage")
private static RegistrySetBuilder.PatchedRegistries getProvider() {
final var registryBuilder = new RegistrySetBuilder();
registryBuilder.add(Registries.CONFIGURED_FEATURE, ModFeatures.Configured::bootstrap);
registryBuilder.add(Registries.PLACED_FEATURE, ModFeatures.Placed::bootstrap);
registryBuilder.add(NeoForgeRegistries.Keys.BIOME_MODIFIERS, BiomeModifiers::bootstrap);
// We need the BIOME registry to be present, so we can use a biome tag, doesn't matter that it's empty
registryBuilder.add(Registries.BIOME, context -> {
});
var regAccess = RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY);
return registryBuilder.buildPatch(regAccess, VanillaRegistries.createLookup());
var factory = new Cloner.Factory();
DataPackRegistriesHooks.getDataPackRegistriesWithDimensions().forEach(data -> data.runWithArguments(factory::addCodec));
return registryBuilder.buildPatch(RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY), VanillaRegistries.createLookup(), factory);
}
}

View file

@ -9,8 +9,6 @@ import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.misc.LevelData;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
@ -25,7 +23,6 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.network.NetworkHooks;
import org.jetbrains.annotations.Nullable;
public class EntityEffectInhibitor extends Entity implements IVisualizable {
@ -123,11 +120,6 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
compound.putInt("amount", this.getAmount());
}
@Override
public Packet<ClientGamePacketListener> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
public boolean skipAttackInteraction(Entity entity) {
return entity instanceof Player player && (!this.level().mayInteract(player, this.blockPosition()) || this.hurt(this.damageSources().playerAttack(player), 0.0F));

View file

@ -9,8 +9,6 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.LongTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
@ -27,7 +25,6 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.HitResult;
import net.neoforged.neoforge.common.util.ITeleporter;
import net.neoforged.neoforge.network.NetworkHooks;
import javax.annotation.Nullable;
import java.util.ArrayList;
@ -157,11 +154,6 @@ public class EntityMoverMinecart extends Minecart {
return Blocks.STONE.defaultBlockState();
}
@Override
public Type getMinecartType() {
return Type.RIDEABLE;
}
@Override
public ItemStack getPickResult() {
return new ItemStack(ModItems.MOVER_CART);
@ -183,11 +175,6 @@ public class EntityMoverMinecart extends Minecart {
this.setDeltaMovement(motion.x * 0.99F, 0, motion.z * 0.99F);
}
@Override
public Packet<ClientGamePacketListener> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
public InteractionResult interact(Player p_38483_, InteractionHand p_38484_) {
return InteractionResult.PASS;

View file

@ -40,6 +40,7 @@ import net.minecraft.world.level.block.MyceliumBlock;
import net.minecraft.world.phys.BlockHitResult;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.client.event.CustomizeGuiOverlayEvent;
import net.neoforged.neoforge.client.event.RenderGuiOverlayEvent;
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
@ -73,9 +74,9 @@ public class ClientEvents {
@SubscribeEvent
public void onDebugRender(CustomizeGuiOverlayEvent.DebugText event) {
var mc = Minecraft.getInstance();
if (mc.options.renderDebug && ModConfig.instance.debugText.get()) {
if (mc.getDebugOverlay().showDebugScreen() && ModConfig.instance.debugText.get()) {
var prefix = ChatFormatting.GREEN + "[" + NaturesAura.MOD_NAME + "]" + ChatFormatting.RESET + " ";
List<String> left = event.getLeft();
var left = event.getLeft();
if (mc.player.isCreative() || mc.player.isSpectator()) {
left.add("");
var amount = new MutableInt(IAuraChunk.DEFAULT_AURA);
@ -190,7 +191,7 @@ public class ClientEvents {
// aura spot debug
ClientEvents.hoveringAuraSpot = null;
if (mc.options.renderDebug && (mc.player.isCreative() || mc.player.isSpectator()) && ModConfig.instance.debugLevel.get()) {
if (mc.getDebugOverlay().showDebugScreen() && (mc.player.isCreative() || mc.player.isSpectator()) && ModConfig.instance.debugLevel.get()) {
var playerEye = mc.player.getEyePosition(event.getPartialTick());
var playerView = mc.player.getViewVector(event.getPartialTick()).normalize();
var range = mc.gameMode.getPickRange();
@ -259,7 +260,7 @@ public class ClientEvents {
var res = event.getWindow();
if (mc.player != null) {
if (!ClientEvents.heldCache.isEmpty()) {
var container = ClientEvents.heldCache.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER, null).orElse(null);
var container = ClientEvents.heldCache.getCapability(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY, null);
var width = Mth.ceil(container.getStoredAura() / (float) container.getMaxAura() * 80);
int conf = ModConfig.instance.cacheBarLocation.get();
@ -290,7 +291,7 @@ public class ClientEvents {
stack.pushPose();
int conf = ModConfig.instance.auraBarLocation.get();
if (!mc.options.renderDebug && (conf != 2 || !(mc.screen instanceof ChatScreen))) {
if (!mc.getDebugOverlay().showDebugScreen() && (conf != 2 || !(mc.screen instanceof ChatScreen))) {
var color = IAuraType.forLevel(mc.level).getColor();
graphics.setColor((color >> 16 & 0xFF) / 255F, (color >> 8 & 0xFF) / 255F, (color & 0xFF) / 255F, 1);
@ -363,16 +364,17 @@ public class ClientEvents {
IAuraContainer container;
var x = res.getGuiScaledWidth() / 2;
var y = res.getGuiScaledHeight() / 2;
if (tile != null && (container = tile.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER, null).orElse(null)) != null) {
if (tile != null && (container = tile.getLevel().getCapability(NaturesAuraAPI.AURA_CONTAINER_BLOCK_CAPABILITY, tile.getBlockPos(), tile.getBlockState(), tile, null)) != null) {
var state = mc.level.getBlockState(pos);
var blockStack = state.getBlock().getCloneItemStack(state, blockHitResult, mc.level, pos, mc.player);
this.drawContainerInfo(graphics, container.getStoredAura(), container.getMaxAura(), container.getAuraColor(),
mc, res, 35, blockStack.getHoverName().getString(), null);
if (tile instanceof BlockEntityNatureAltar) {
var tileStack = ((BlockEntityNatureAltar) tile).getItemHandler().getStackInSlot(0);
var itemHandler = tile.getLevel().getCapability(Capabilities.ItemHandler.BLOCK, tile.getBlockPos(), tile.getBlockState(), tile, null);
var tileStack = itemHandler.getStackInSlot(0);
if (!tileStack.isEmpty()) {
var stackCont = tileStack.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER, null).orElse(null);
var stackCont = tileStack.getCapability(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY);
if (stackCont != null) {
this.drawContainerInfo(graphics, stackCont.getStoredAura(), stackCont.getMaxAura(), stackCont.getAuraColor(),
mc, res, 55, tileStack.getHoverName().getString(), null);
@ -385,7 +387,8 @@ public class ClientEvents {
mc, res, 35, I18n.get("block.naturesaura.rf_converter"),
storage.getEnergyStored() + " / " + storage.getMaxEnergyStored() + " RF");
} else if (tile instanceof BlockEntityGratedChute chute) {
var itemStack = chute.getItemHandler().getStackInSlot(0);
var itemHandler = tile.getLevel().getCapability(Capabilities.ItemHandler.BLOCK, tile.getBlockPos(), tile.getBlockState(), tile, null);
var itemStack = itemHandler.getStackInSlot(0);
if (itemStack.isEmpty()) {
graphics.drawString(mc.font,
@ -407,7 +410,8 @@ public class ClientEvents {
graphics.blit(ClientEvents.OVERLAYS, x - 18, y - 18, u, 0, 16, 16, 256, 256);
RenderSystem.enableDepthTest();
} else if (tile instanceof BlockEntityAuraTimer timer) {
var itemStack = timer.getItemHandler().getStackInSlot(0);
var itemHandler = tile.getLevel().getCapability(Capabilities.ItemHandler.BLOCK, tile.getBlockPos(), tile.getBlockState(), tile, null);
var itemStack = itemHandler.getStackInSlot(0);
if (!itemStack.isEmpty()) {
Helper.renderItemInGui(graphics, itemStack, x - 20, y - 20, 1);
graphics.drawString(mc.font, ChatFormatting.GRAY + this.createTimeString(timer.getTotalTime()), x + 5, y - 11, 0xFFFFFF);

View file

@ -33,14 +33,14 @@ import java.util.UUID;
public class CommonEvents {
private static final Method GET_LOADED_CHUNKS_METHOD = ObfuscationReflectionHelper.findMethod(ChunkMap.class, "m_140416_");
private static final Method GET_LOADED_CHUNKS_METHOD = ObfuscationReflectionHelper.findMethod(ChunkMap.class, "getChunks");
private static final ListMultimap<UUID, ChunkPos> PENDING_AURA_CHUNKS = ArrayListMultimap.create();
@SubscribeEvent
public void onChunkUnload(ChunkEvent.Unload event) {
var iChunk = event.getChunk();
if (iChunk instanceof LevelChunk chunk) {
var auraChunk = chunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT).get(chunk);
var auraChunk = chunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT);
if (auraChunk instanceof AuraChunk) {
var data = (LevelData) ILevelData.getLevelData(chunk.getLevel());
data.auraChunksWithSpots.remove(chunk.getPos().toLong());
@ -76,7 +76,7 @@ public class CommonEvents {
var chunk = holder.getTickingChunk();
if (chunk == null)
continue;
var auraChunk = (AuraChunk) chunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT).get(chunk);
var auraChunk = (AuraChunk) chunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT);
if (auraChunk != null)
auraChunk.update();
}
@ -116,7 +116,7 @@ public class CommonEvents {
var chunk = Helper.getLoadedChunk(player.level(), pos.x, pos.z);
if (!(chunk instanceof LevelChunk levelChunk))
return false;
var auraChunk = (AuraChunk) levelChunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT).get(levelChunk);
var auraChunk = (AuraChunk) levelChunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT);
if (auraChunk == null)
return false;
PacketHandler.sendTo(player, auraChunk.makePacket());

View file

@ -4,15 +4,12 @@ import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.container.ItemAuraContainer;
import de.ellpeck.naturesaura.api.render.ITrinketItem;
import de.ellpeck.naturesaura.enchant.ModEnchantments;
import de.ellpeck.naturesaura.reg.ICustomCreativeTab;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.player.Player;
@ -21,47 +18,37 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.common.capabilities.Capability;
import net.neoforged.neoforge.common.capabilities.ICapabilityProvider;
import net.neoforged.neoforge.common.util.LazyOptional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class ItemAuraCache extends ItemImpl implements ITrinketItem, ICustomCreativeTab {
private final int capacity;
public ItemAuraCache(String name, int capacity) {
public ItemAuraCache(String name) {
super(name, new Properties().stacksTo(1));
this.capacity = capacity;
}
@Override
public void inventoryTick(ItemStack stackIn, Level levelIn, Entity entityIn, int itemSlot, boolean isSelected) {
if (!levelIn.isClientSide && entityIn instanceof Player player) {
if (player.isShiftKeyDown() && stackIn.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER).isPresent()) {
var container = stackIn.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER).orElse(null);
if (container.getStoredAura() <= 0) {
return;
}
for (var i = 0; i < player.getInventory().getContainerSize(); i++) {
var stack = player.getInventory().getItem(i);
var recharge = stack.getCapability(NaturesAuraAPI.CAP_AURA_RECHARGE).orElse(null);
if (recharge != null) {
if (recharge.rechargeFromContainer(container, itemSlot, i, player.getInventory().selected == i))
break;
} else if (stack.getEnchantmentLevel(ModEnchantments.AURA_MENDING) > 0) {
var mainSize = player.getInventory().items.size();
var isArmor = i >= mainSize && i < mainSize + player.getInventory().armor.size();
if ((isArmor || player.getInventory().selected == i) && Helper.rechargeAuraItem(stack, container, 1000))
break;
}
if (!levelIn.isClientSide && entityIn instanceof Player player && player.isShiftKeyDown()) {
var container = stackIn.getCapability(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY);
if (container == null || container.getStoredAura() <= 0)
return;
for (var i = 0; i < player.getInventory().getContainerSize(); i++) {
var stack = player.getInventory().getItem(i);
var recharge = stack.getCapability(NaturesAuraAPI.AURA_RECHARGE_CAPABILITY);
if (recharge != null) {
if (recharge.rechargeFromContainer(container, itemSlot, i, player.getInventory().selected == i))
break;
} else if (stack.getEnchantmentLevel(ModEnchantments.AURA_MENDING) > 0) {
var mainSize = player.getInventory().items.size();
var isArmor = i >= mainSize && i < mainSize + player.getInventory().armor.size();
if ((isArmor || player.getInventory().selected == i) && Helper.rechargeAuraItem(stack, container, 1000))
break;
}
}
}
}
@Override
@ -69,10 +56,9 @@ public class ItemAuraCache extends ItemImpl implements ITrinketItem, ICustomCrea
var ret = new ArrayList<ItemStack>();
ret.add(new ItemStack(this));
var full = new ItemStack(this);
full.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER).ifPresent(container -> {
container.storeAura(container.getMaxAura(), false);
ret.add(full);
});
var container = full.getCapability(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY);
container.storeAura(container.getMaxAura(), false);
ret.add(full);
return ret;
}
@ -83,37 +69,16 @@ public class ItemAuraCache extends ItemImpl implements ITrinketItem, ICustomCrea
@Override
public int getBarWidth(ItemStack stack) {
if (stack.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER).isPresent()) {
var container = stack.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER).orElse(null);
return Math.round(container.getStoredAura() / (float) container.getMaxAura() * 13);
}
return 0;
var container = stack.getCapability(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY);
return container != null ? Math.round(container.getStoredAura() / (float) container.getMaxAura() * 13) : 0;
}
@Override
public int getBarColor(ItemStack stack) {
var cap = stack.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER).orElse(null);
var cap = stack.getCapability(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY);
return cap != null ? cap.getAuraColor() : super.getBarColor(stack);
}
@Nullable
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
return new ICapabilityProvider() {
private final LazyOptional<ItemAuraContainer> container = LazyOptional.of(() -> new ItemAuraContainer(stack, null, ItemAuraCache.this.capacity));
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable Direction facing) {
if (capability == NaturesAuraAPI.CAP_AURA_CONTAINER) {
return this.container.cast();
} else {
return LazyOptional.empty();
}
}
};
}
@Override
@OnlyIn(Dist.CLIENT)
public void render(ItemStack stack, Player player, RenderType type, PoseStack matrices, MultiBufferSource buffer, int packedLight, boolean isHolding) {
@ -126,4 +91,5 @@ public class ItemAuraCache extends ItemImpl implements ITrinketItem, ICustomCrea
Minecraft.getInstance().getItemRenderer().renderStatic(stack, ItemDisplayContext.GROUND, packedLight, OverlayTexture.NO_OVERLAY, matrices, buffer, player.level(), 0);
}
}
}

View file

@ -2,6 +2,7 @@ package de.ellpeck.naturesaura.items;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
@ -12,8 +13,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.SpawnerBlockEntity;
import net.minecraft.world.phys.AABB;
import net.neoforged.neoforge.common.capabilities.Capabilities;
import net.neoforged.neoforge.registries.ForgeRegistries;
import net.neoforged.neoforge.capabilities.Capabilities;
public class ItemLootFinder extends ItemImpl {
@ -34,7 +34,7 @@ public class ItemLootFinder extends ItemImpl {
var pos = playerIn.blockPosition();
Helper.getBlockEntitiesInArea(levelIn, pos, 64, tile -> {
if (tile.getCapability(Capabilities.ITEM_HANDLER).isPresent() || tile instanceof SpawnerBlockEntity || ForgeRegistries.BLOCK_ENTITY_TYPES.getKey(tile.getType()).getNamespace().equals("lootr")) {
if (tile.getLevel().getCapability(Capabilities.ItemHandler.BLOCK, tile.getBlockPos(), tile.getBlockState(), tile, null) != null || tile instanceof SpawnerBlockEntity || BuiltInRegistries.BLOCK_ENTITY_TYPE.getKey(tile.getType()).getNamespace().equals("lootr")) {
inst.spawnMagicParticle(
tile.getBlockPos().getX() + 0.5F, tile.getBlockPos().getY() + 0.5F, tile.getBlockPos().getZ() + 0.5F,
0F, 0F, 0F, 0xf5f10a, 6F, 20 * 60, 0F, false, true);
@ -42,7 +42,7 @@ public class ItemLootFinder extends ItemImpl {
return false;
});
for (var entity : levelIn.getEntitiesOfClass(Entity.class, new AABB(pos).inflate(64))) {
if (!(entity instanceof LivingEntity) && entity.getCapability(Capabilities.ITEM_HANDLER).isPresent()) {
if (!(entity instanceof LivingEntity) && entity.getCapability(Capabilities.ItemHandler.ENTITY) != null) {
inst.spawnMagicParticle(
entity.getX(), entity.getEyeY(), entity.getZ(),
0F, 0F, 0F, 0xf5f10a, 6F, 20 * 60, 0F, false, true);

View file

@ -1,11 +1,10 @@
package de.ellpeck.naturesaura.items.tools;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.reg.IModItem;
import de.ellpeck.naturesaura.reg.ModArmorMaterial;
import de.ellpeck.naturesaura.reg.ModRegistry;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.EquipmentSlot;
@ -13,15 +12,17 @@ import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.*;
import net.minecraft.world.item.ArmorItem;
import net.minecraft.world.item.ArmorMaterial;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items;
import net.minecraft.world.phys.AABB;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.common.NeoForgeMod;
import net.neoforged.neoforge.event.TickEvent;
import net.neoforged.neoforge.event.entity.living.LivingAttackEvent;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;
import javax.annotation.Nullable;
import java.util.Comparator;
import java.util.Map;
import java.util.UUID;
@ -41,7 +42,7 @@ public class ItemArmor extends ArmorItem implements IModItem {
}
public static boolean isFullSetEquipped(LivingEntity entity, ArmorMaterial material) {
var set = ItemArmor.SETS.computeIfAbsent(material, m -> ForgeRegistries.ITEMS.getValues().stream()
var set = ItemArmor.SETS.computeIfAbsent(material, m -> BuiltInRegistries.ITEM.stream()
.filter(i -> i instanceof ItemArmor && ((ItemArmor) i).getMaterial() == material)
.sorted(Comparator.comparingInt(i -> ((ItemArmor) i).getEquipmentSlot().ordinal()))
.toArray(Item[]::new));
@ -59,12 +60,6 @@ public class ItemArmor extends ArmorItem implements IModItem {
return this.baseName;
}
@Nullable
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
return Helper.makeRechargeProvider(stack, false);
}
@Mod.EventBusSubscriber
private static final class EventHandler {
@ -89,7 +84,7 @@ public class ItemArmor extends ArmorItem implements IModItem {
public static void update(TickEvent.PlayerTickEvent event) {
var player = event.player;
var speed = player.getAttribute(Attributes.MOVEMENT_SPEED);
var step = player.getAttribute(NeoForgeMod.STEP_HEIGHT_ADDITION.get());
var step = player.getAttribute(NeoForgeMod.STEP_HEIGHT.value());
var key = NaturesAura.MOD_ID + ":sky_equipped";
var nbt = player.getPersistentData();
var equipped = ItemArmor.isFullSetEquipped(player, ModArmorMaterial.SKY);
@ -103,8 +98,8 @@ public class ItemArmor extends ArmorItem implements IModItem {
} else if (!equipped && nbt.getBoolean(key)) {
// we just unequipped it
nbt.putBoolean(key, false);
step.removeModifier(ItemArmor.SKY_STEP_MODIFIER);
speed.removeModifier(ItemArmor.SKY_MOVEMENT_MODIFIER);
step.removeModifier(ItemArmor.SKY_STEP_MODIFIER.getId());
speed.removeModifier(ItemArmor.SKY_MOVEMENT_MODIFIER.getId());
}
}

View file

@ -7,7 +7,6 @@ import de.ellpeck.naturesaura.reg.ICustomItemModel;
import de.ellpeck.naturesaura.reg.IModItem;
import de.ellpeck.naturesaura.reg.ModRegistry;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
@ -17,9 +16,6 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Tier;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.common.capabilities.ICapabilityProvider;
import javax.annotation.Nullable;
public class ItemAxe extends AxeItem implements IModItem, ICustomItemModel {
@ -63,12 +59,6 @@ public class ItemAxe extends AxeItem implements IModItem, ICustomItemModel {
return super.use(level, player, hand);
}
@Nullable
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
return Helper.makeRechargeProvider(stack, true);
}
@Override
public void generateCustomItemModel(ItemModelGenerator generator) {
if (this == ModItems.SKY_AXE || this == ModItems.DEPTH_AXE)

View file

@ -1,13 +1,11 @@
package de.ellpeck.naturesaura.items.tools;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.data.ItemModelGenerator;
import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.reg.ICustomItemModel;
import de.ellpeck.naturesaura.reg.IModItem;
import de.ellpeck.naturesaura.reg.ModRegistry;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
@ -21,9 +19,6 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.BushBlock;
import net.minecraft.world.level.block.LeavesBlock;
import net.minecraft.world.phys.BlockHitResult;
import net.neoforged.neoforge.common.capabilities.ICapabilityProvider;
import javax.annotation.Nullable;
public class ItemHoe extends HoeItem implements IModItem, ICustomItemModel {
@ -111,12 +106,6 @@ public class ItemHoe extends HoeItem implements IModItem, ICustomItemModel {
return this.baseName;
}
@Nullable
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
return Helper.makeRechargeProvider(stack, true);
}
@Override
public void generateCustomItemModel(ItemModelGenerator generator) {
generator.withExistingParent(this.getBaseName(), "item/handheld").texture("layer0", "item/" + this.getBaseName());

View file

@ -10,7 +10,6 @@ import de.ellpeck.naturesaura.reg.ICustomItemModel;
import de.ellpeck.naturesaura.reg.IModItem;
import de.ellpeck.naturesaura.reg.ModRegistry;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
@ -26,9 +25,6 @@ import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.neoforged.neoforge.common.Tags;
import net.neoforged.neoforge.common.capabilities.ICapabilityProvider;
import javax.annotation.Nullable;
public class ItemPickaxe extends PickaxeItem implements IModItem, ICustomItemModel {
@ -104,12 +100,6 @@ public class ItemPickaxe extends PickaxeItem implements IModItem, ICustomItemMod
return super.use(level, player, hand);
}
@Nullable
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
return Helper.makeRechargeProvider(stack, true);
}
@Override
public void generateCustomItemModel(ItemModelGenerator generator) {
if (this == ModItems.DEPTH_PICKAXE)

View file

@ -1,6 +1,5 @@
package de.ellpeck.naturesaura.items.tools;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.data.ItemModelGenerator;
import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.reg.ICustomItemModel;
@ -8,23 +7,19 @@ import de.ellpeck.naturesaura.reg.IModItem;
import de.ellpeck.naturesaura.reg.ModRegistry;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ShovelItem;
import net.minecraft.world.item.Tier;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.phys.BlockHitResult;
import net.neoforged.neoforge.common.capabilities.ICapabilityProvider;
import javax.annotation.Nullable;
import java.util.ArrayList;
public class ItemShovel extends ShovelItem implements IModItem, ICustomItemModel {
@ -126,12 +121,6 @@ public class ItemShovel extends ShovelItem implements IModItem, ICustomItemModel
return this.baseName;
}
@Nullable
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
return Helper.makeRechargeProvider(stack, true);
}
@Override
public void generateCustomItemModel(ItemModelGenerator generator) {
generator.withExistingParent(this.getBaseName(), "item/handheld").texture("layer0", "item/" + this.getBaseName());

View file

@ -1,12 +1,10 @@
package de.ellpeck.naturesaura.items.tools;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.data.ItemModelGenerator;
import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.reg.ICustomItemModel;
import de.ellpeck.naturesaura.reg.IModItem;
import de.ellpeck.naturesaura.reg.ModRegistry;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.Mth;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
@ -19,11 +17,8 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.SwordItem;
import net.minecraft.world.item.Tier;
import net.minecraft.world.phys.AABB;
import net.neoforged.neoforge.common.capabilities.ICapabilityProvider;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
public class ItemSword extends SwordItem implements IModItem, ICustomItemModel {
private final String baseName;
@ -67,12 +62,6 @@ public class ItemSword extends SwordItem implements IModItem, ICustomItemModel {
return super.getSweepHitBox(stack, player, target);
}
@Nullable
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
return Helper.makeRechargeProvider(stack, true);
}
@Override
public void generateCustomItemModel(ItemModelGenerator generator) {
generator.withExistingParent(this.getBaseName(), "item/handheld").texture("layer0", "item/" + this.getBaseName());

View file

@ -70,6 +70,11 @@ public class LevelData extends SavedData implements ILevelData {
return compound;
}
@Override
public boolean isDirty() {
return true;
}
@Override
public ItemStackHandlerNA getEnderStorage(String name) {
return this.enderStorages.computeIfAbsent(name, n -> new ItemStackHandlerNA(27));

View file

@ -61,7 +61,7 @@ public class PacketAuraChunk implements CustomPacketPayload {
var chunk = level.getChunk(this.chunkX, this.chunkZ);
if (chunk.isEmpty())
return false;
var auraChunk = (AuraChunk) chunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT).get(chunk);
var auraChunk = (AuraChunk) chunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT);
if (auraChunk == null)
return false;
auraChunk.setSpots(this.drainSpots);

View file

@ -7,11 +7,12 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.common.Mod.EventBusSubscriber;
import net.neoforged.fml.common.Mod.EventBusSubscriber.Bus;
import net.neoforged.neoforge.network.PacketDistributor;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent;
@Mod.EventBusSubscriber
@EventBusSubscriber(bus = Bus.MOD)
public final class PacketHandler {
@SubscribeEvent

View file

@ -29,7 +29,7 @@ public class PotionBreathless extends PotionImpl {
}
@Override
public boolean isDurationEffectTick(int duration, int amplifier) {
public boolean shouldApplyEffectTickThisTick(int duration, int amplifier) {
var mod = 200 >> amplifier;
return mod > 0 && duration % mod == 0 && this.random.nextBoolean();
}
@ -38,4 +38,5 @@ public class PotionBreathless extends PotionImpl {
public void applyEffectTick(LivingEntity entity, int amplifier) {
entity.hurt(entity.damageSources().magic(), 1F);
}
}

View file

@ -46,8 +46,8 @@ public class AltarRecipe extends ModRecipe {
private static final Codec<AltarRecipe> CODEC = RecordCodecBuilder.create(i -> i.group(
Ingredient.CODEC.fieldOf("input").forGetter(r -> r.input),
ItemStack.CODEC.fieldOf("output").forGetter(r -> r.output),
Ingredient.CODEC.fieldOf("catalyst").forGetter(r -> r.catalyst),
ItemStack.ITEM_WITH_COUNT_CODEC.fieldOf("output").forGetter(r -> r.output),
Ingredient.CODEC.optionalFieldOf("catalyst", Ingredient.EMPTY).forGetter(r -> r.catalyst),
Codec.INT.fieldOf("aura").forGetter(r -> r.aura),
Codec.INT.fieldOf("time").forGetter(r -> r.time)
).apply(i, AltarRecipe::new));

View file

@ -43,7 +43,7 @@ public class OfferingRecipe extends ModRecipe {
private static final Codec<OfferingRecipe> CODEC = RecordCodecBuilder.create(i -> i.group(
Ingredient.CODEC.fieldOf("input").forGetter(r -> r.input),
Ingredient.CODEC.fieldOf("start_item").forGetter(r -> r.startItem),
ItemStack.CODEC.fieldOf("output").forGetter(r -> r.output)
ItemStack.ITEM_WITH_COUNT_CODEC.fieldOf("output").forGetter(r -> r.output)
).apply(i, OfferingRecipe::new));
@Override

View file

@ -17,19 +17,19 @@ public class TreeRitualRecipe extends ModRecipe {
public final Ingredient saplingType;
public final List<Ingredient> ingredients;
public final ItemStack result;
public final ItemStack output;
public final int time;
public TreeRitualRecipe(Ingredient saplingType, ItemStack result, int time, List<Ingredient> ingredients) {
public TreeRitualRecipe(Ingredient saplingType, ItemStack output, int time, List<Ingredient> ingredients) {
this.saplingType = saplingType;
this.ingredients = ingredients;
this.result = result;
this.output = output;
this.time = time;
}
@Override
public ItemStack getResultItem(RegistryAccess access) {
return this.result;
return this.output;
}
@Override
@ -46,7 +46,7 @@ public class TreeRitualRecipe extends ModRecipe {
private static final Codec<TreeRitualRecipe> CODEC = RecordCodecBuilder.create(i -> i.group(
Ingredient.CODEC.fieldOf("sapling").forGetter(r -> r.saplingType),
ItemStack.CODEC.fieldOf("result").forGetter(r -> r.result),
ItemStack.ITEM_WITH_COUNT_CODEC.fieldOf("output").forGetter(r -> r.output),
Codec.INT.fieldOf("time").forGetter(r -> r.time),
Ingredient.CODEC.listOf().fieldOf("ingredients").forGetter(recipe -> recipe.ingredients)
).apply(i, TreeRitualRecipe::new));
@ -71,7 +71,7 @@ public class TreeRitualRecipe extends ModRecipe {
for (var ing : recipe.ingredients)
ing.toNetwork(buffer);
recipe.saplingType.toNetwork(buffer);
buffer.writeItem(recipe.result);
buffer.writeItem(recipe.output);
buffer.writeInt(recipe.time);
}

View file

@ -3,11 +3,13 @@ package de.ellpeck.naturesaura.reg;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.container.ItemAuraContainer;
import de.ellpeck.naturesaura.api.misc.ILevelData;
import de.ellpeck.naturesaura.blocks.*;
import de.ellpeck.naturesaura.blocks.tiles.BlockEntityAuraBloom;
import de.ellpeck.naturesaura.blocks.tiles.BlockEntityEnderCrate;
import de.ellpeck.naturesaura.blocks.tiles.ModBlockEntities;
import de.ellpeck.naturesaura.compat.Compat;
import de.ellpeck.naturesaura.compat.patchouli.PatchouliCompat;
import de.ellpeck.naturesaura.enchant.AuraMendingEnchantment;
import de.ellpeck.naturesaura.enchant.ModEnchantments;
@ -170,8 +172,8 @@ public final class ModRegistry {
new ItemImpl("infused_iron"),
new ItemImpl("ancient_stick"),
new ItemColorChanger(),
new ItemAuraCache("aura_cache", 400000),
new ItemAuraCache("aura_trove", 1200000),
new ItemAuraCache("aura_cache"),
new ItemAuraCache("aura_trove"),
new ItemShockwaveCreator(),
new ItemMultiblockMaker(),
temp = new ItemImpl("bottle_two_the_rebottling"),
@ -248,8 +250,10 @@ public final class ModRegistry {
event.register(Registries.MENU, h -> {
h.register(new ResourceLocation(NaturesAura.MOD_ID, "ender_crate"), IMenuTypeExtension.create((windowId, inv, data) -> {
var tile = inv.player.level().getBlockEntity(data.readBlockPos());
if (tile instanceof BlockEntityEnderCrate crate)
return new ContainerEnderCrate(ModContainers.ENDER_CRATE, windowId, inv.player, crate.getItemHandler());
if (tile instanceof BlockEntityEnderCrate) {
var handler = tile.getLevel().getCapability(ItemHandler.BLOCK, tile.getBlockPos(), tile.getBlockState(), tile, null);
return new ContainerEnderCrate(ModContainers.ENDER_CRATE, windowId, inv.player, handler);
}
return null;
}));
h.register(new ResourceLocation(NaturesAura.MOD_ID, "ender_access"), IMenuTypeExtension.create((windowId, inv, data) -> {
@ -336,13 +340,10 @@ public final class ModRegistry {
@SubscribeEvent
public static void registerCapabilities(RegisterCapabilitiesEvent event) {
event.registerBlockEntity(FluidHandler.BLOCK, ModBlockEntities.SPRING, (e, c) -> e.tank);
event.registerBlockEntity(EnergyStorage.BLOCK, ModBlockEntities.RF_CONVERTER, (e, c) -> e.storage);
event.registerBlockEntity(NaturesAuraAPI.AURA_CONTAINER_BLOCK_CAPABILITY, ModBlockEntities.NATURE_ALTAR, (e, c) -> e.container);
event.registerBlockEntity(NaturesAuraAPI.AURA_CONTAINER_BLOCK_CAPABILITY, ModBlockEntities.ANCIENT_LEAVES, (e, c) -> e.container);
event.registerBlockEntity(NaturesAuraAPI.AURA_CONTAINER_BLOCK_CAPABILITY, ModBlockEntities.END_FLOWER, (e, c) -> e.container);
event.registerBlockEntity(ItemHandler.BLOCK, ModBlockEntities.BLAST_FURNACE_BOOSTER, (e, c) -> e.getItemHandler());
event.registerBlockEntity(ItemHandler.BLOCK, ModBlockEntities.OFFERING_TABLE, (e, c) -> e.items);
event.registerBlockEntity(ItemHandler.BLOCK, ModBlockEntities.GRATED_CHUTE, (e, c) -> e.items);
@ -350,6 +351,18 @@ public final class ModRegistry {
event.registerBlockEntity(ItemHandler.BLOCK, ModBlockEntities.WOOD_STAND, (e, c) -> e.items);
event.registerBlockEntity(ItemHandler.BLOCK, ModBlockEntities.ENDER_CRATE, (e, c) -> e.canOpen() ? e.wrappedEnderStorage : null);
event.registerBlockEntity(ItemHandler.BLOCK, ModBlockEntities.AURA_TIMER, (e, c) -> e.itemHandler);
event.registerItem(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY, (s, c) -> new ItemAuraContainer(s, null, 400000), ModItems.AURA_CACHE);
event.registerItem(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY, (s, c) -> new ItemAuraContainer(s, null, 1200000), ModItems.AURA_TROVE);
for (var item : ModRegistry.ALL_ITEMS) {
if (item instanceof ItemArmor) {
event.registerItem(NaturesAuraAPI.AURA_RECHARGE_CAPABILITY, Helper.makeRechargeProvider(false), (Item) item);
} else if (item instanceof ItemAxe || item instanceof ItemPickaxe || item instanceof ItemShovel || item instanceof ItemHoe || item instanceof ItemSword) {
event.registerItem(NaturesAuraAPI.AURA_RECHARGE_CAPABILITY, Helper.makeRechargeProvider(true), (Item) item);
}
}
Compat.addCapabilities(event);
}
public static Block createFlowerPot(Block block) {

View file

@ -18,7 +18,6 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.items.IItemHandler;
import top.theillusivec4.curios.api.CuriosApi;
import java.util.HashSet;
@ -61,8 +60,9 @@ public class PlayerLayerTrinkets extends RenderLayer<AbstractClientPlayer, Playe
}
if (Compat.hasCompat("curios")) {
IItemHandler handler = CuriosApi.getCuriosHelper().getEquippedCurios(player).orElse(null);
if (handler != null) {
var inventory = CuriosApi.getCuriosInventory(player).orElse(null);
if (inventory != null) {
var handler = inventory.getEquippedCurios();
for (var i = 0; i < handler.getSlots(); i++)
this.renderStack(handler.getStackInSlot(i), player, type, main, second, matrices, buffer, packedLight);
}
@ -84,4 +84,5 @@ public class PlayerLayerTrinkets extends RenderLayer<AbstractClientPlayer, Playe
}
}
}
}

View file

@ -4,22 +4,22 @@
# Note that there are a couple of TOML lists in this file.
# Find more information on toml format here: https://github.com/toml-lang/toml
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
modLoader="javafml" #mandatory
# A version range to match for said mod loader - for regular FML @Mod it will be the forge version
loaderVersion="${loader_version_range}" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions.
modLoader = "javafml" #mandatory
# A version range to match for said mod loader - for regular FML @Mod it will be the the FML version. This is currently 47.
loaderVersion = "${loader_version_range}" #mandatory
# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties.
# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here.
license="${mod_license}"
license = "${mod_license}"
# A URL to refer people to when problems occur with this mod
#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional
# A list of mods - how many allowed here is determined by the individual mod loader
[[mods]] #mandatory
# The modid of the mod
modId="${mod_id}" #mandatory
modId = "${mod_id}" #mandatory
# The version number of the mod
version="${mod_version}" #mandatory
version = "${mod_version}" #mandatory
# A display name for the mod
displayName="${mod_name}" #mandatory
displayName = "${mod_name}" #mandatory
# A URL to query for updates for this mod. See the JSON update specification https://docs.minecraftforge.net/en/latest/misc/updatechecker/
#updateJSONURL="https://change.me.example.invalid/updates.json" #optional
# A URL for the "homepage" for this mod, displayed in the mod UI
@ -29,7 +29,7 @@ displayName="${mod_name}" #mandatory
# A text field displayed in the mod UI
#credits="" #optional
# A text field displayed in the mod UI
authors="${mod_authors}" #optional
authors = "${mod_authors}" #optional
# Display Test controls the display for your mod in the server connection screen
# MATCH_VERSION means that your mod will cause a red X if the versions on client and server differ. This is the default behaviour and should be what you choose if you have server and client elements to your mod.
# IGNORE_SERVER_VERSION means that your mod will not cause a red X if it's present on the server but not on the client. This is what you should use if you're a server only mod.
@ -39,29 +39,33 @@ authors="${mod_authors}" #optional
#displayTest="MATCH_VERSION" # MATCH_VERSION is the default if nothing is specified (#optional)
# The description text for the mod (multi line!) (#mandatory)
description='''${mod_description}'''
description = '''${mod_description}'''
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
[[dependencies.${mod_id}]] #optional
[[dependencies.${ mod_id }]] #optional
# the modid of the dependency
modId="forge" #mandatory
# Does this dependency have to exist - if not, ordering below must be specified
mandatory=true #mandatory
modId = "neoforge" #mandatory
# The type of the dependency. Can be one of "required", "optional", "incompatible" or "discouraged" (case insensitive).
# 'required' requires the mod to exist, 'optional' does not
# 'incompatible' will prevent the game from loading when the mod exists, and 'discouraged' will show a warning
type = "required" #mandatory
# Optional field describing why the dependency is required or why it is incompatible
# reason="..."
# The version range of the dependency
versionRange="${forge_version_range}" #mandatory
# An ordering relationship for the dependency - BEFORE or AFTER required if the dependency is not mandatory
versionRange = "${neo_version_range}" #mandatory
# An ordering relationship for the dependency.
# BEFORE - This mod is loaded BEFORE the dependency
# AFTER - This mod is loaded AFTER the dependency
ordering="NONE"
ordering = "NONE"
# Side this dependency is applied on - BOTH, CLIENT, or SERVER
side="BOTH"
side = "BOTH"
# Here's another dependency
[[dependencies.${mod_id}]]
modId="minecraft"
mandatory=true
[[dependencies.${ mod_id }]]
modId = "minecraft"
type = "required"
# This version range declares a minimum of the current minecraft version up to but not including the next major version
versionRange="${minecraft_version_range}"
ordering="NONE"
side="BOTH"
versionRange = "${minecraft_version_range}"
ordering = "NONE"
side = "BOTH"
# Features are specific properties of the game environment, that you may want to declare you require. This example declares
# that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't

View file

@ -10,7 +10,7 @@
"tag": "forge:nuggets/gold"
},
"G": {
"item": "minecraft:grass"
"item": "minecraft:grass_block"
},
"L": {
"tag": "minecraft:leaves"
@ -20,4 +20,4 @@
"item": "naturesaura:gold_fiber",
"count": 4
}
}
}