Compare commits

...

3 commits

Author SHA1 Message Date
Ell f2547e6555 a lot more 1.20.4 port work 2024-03-10 15:54:58 +01:00
Ell 5a4a191973 a bunch more 1.20.4 work 2024-03-10 11:29:12 +01:00
Ell 9010b9708e packet conversion 2024-03-10 10:41:34 +01:00
89 changed files with 719 additions and 816 deletions

View file

@ -15,6 +15,8 @@ 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;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerPlayer;
@ -42,12 +44,9 @@ import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.common.capabilities.Capability;
import net.neoforged.neoforge.common.util.LazyOptional;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.registries.ForgeRegistries;
import net.neoforged.neoforge.registries.IForgeRegistry;
import net.neoforged.neoforge.common.capabilities.ICapabilityProvider;
import net.neoforged.neoforge.items.IItemHandlerModifiable;
import top.theillusivec4.curios.api.CuriosApi;
import top.theillusivec4.curios.api.SlotResult;
@ -167,7 +166,7 @@ public final class Helper {
public static InteractionResult putStackOnTile(Player player, InteractionHand hand, BlockPos pos, int slot, boolean sound) {
var tile = player.level().getBlockEntity(pos);
if (tile instanceof BlockEntityImpl) {
var handler = ((BlockEntityImpl) tile).getItemHandler();
var handler = (IItemHandlerModifiable) tile.getLevel().getCapability(Capabilities.ItemHandler.BLOCK, tile.getBlockPos(), tile.getBlockState(), tile, null);
if (handler != null) {
var handStack = player.getItemInHand(hand);
if (!handStack.isEmpty()) {
@ -230,7 +229,7 @@ public final class Helper {
public static BlockState getStateFromString(String raw) {
var split = raw.split("\\[");
var block = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(split[0]));
var block = BuiltInRegistries.BLOCK.get(new ResourceLocation(split[0]));
if (block != null) {
var state = block.defaultBlockState();
if (split.length > 1) {
@ -261,7 +260,7 @@ public final class Helper {
public static void addAdvancement(Player player, ResourceLocation advancement, String criterion) {
if (!(player instanceof ServerPlayer playerMp))
return;
var adv = playerMp.level().getServer().getAdvancements().getAdvancement(advancement);
var adv = playerMp.level().getServer().getAdvancements().get(advancement);
if (adv != null)
playerMp.getAdvancements().award(adv, criterion);
}
@ -295,17 +294,17 @@ public final class Helper {
}
// This is how @ObjectHolder SHOULD work...
public static <T> void populateObjectHolders(Class<?> clazz, IForgeRegistry<T> registry) {
public static <T> void populateObjectHolders(Class<?> clazz, Registry<T> registry) {
for (var entry : clazz.getFields()) {
if (!Modifier.isStatic(entry.getModifiers()))
continue;
var location = new ResourceLocation(NaturesAura.MOD_ID, entry.getName().toLowerCase(Locale.ROOT));
if (!registry.containsKey(location)) {
NaturesAura.LOGGER.fatal("Couldn't find entry named " + location + " in registry " + registry.getRegistryName());
NaturesAura.LOGGER.fatal("Couldn't find entry named " + location + " in registry");
continue;
}
try {
entry.set(null, registry.getValue(location));
entry.set(null, registry.get(location));
} catch (IllegalAccessException e) {
NaturesAura.LOGGER.error(e);
}

View file

@ -5,9 +5,11 @@ import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.misc.ILevelData;
import de.ellpeck.naturesaura.api.multiblock.IMultiblock;
import de.ellpeck.naturesaura.blocks.multi.Multiblock;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.misc.LevelData;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Tuple;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
@ -37,9 +39,9 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
private boolean auraPlayerInteraction(Player player, int amount, boolean extract, boolean simulate) {
if (extract && player.isCreative())
return true;
var stack = Helper.getEquippedItem(s -> s.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER).isPresent(), player, false);
var stack = Helper.getEquippedItem(s -> s.getCapability(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY) != null, player, false);
if (!stack.isEmpty()) {
var container = stack.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER).orElse(null);
var container = stack.getCapability(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY);
if (extract) {
return container.drainAura(amount, simulate) > 0;
} else {
@ -182,4 +184,25 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
return highest;
}
@Override
public ILevelData getLevelData(Level level) {
if (level instanceof ServerLevel server) {
var ret = server.getDataStorage().computeIfAbsent(LevelData.FACTORY, "level_data");
if (ret.level == null)
ret.level = level;
return ret;
} else {
if (LevelData.client == null || LevelData.client.level != level) {
LevelData.client = new LevelData();
LevelData.client.level = level;
}
return LevelData.client;
}
}
@Override
public IAuraChunk createAuraChunk() {
return new AuraChunk();
}
}

View file

@ -5,10 +5,10 @@ import de.ellpeck.naturesaura.api.aura.type.BasicAuraType;
import de.ellpeck.naturesaura.api.misc.WeightedOre;
import de.ellpeck.naturesaura.chunk.effect.OreSpawnEffect;
import de.ellpeck.naturesaura.chunk.effect.PlantBoostEffect;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.neoforge.common.ModConfigSpec;
import net.neoforged.neoforge.common.ModConfigSpec.ConfigValue;
import net.neoforged.neoforge.registries.ForgeRegistries;
import java.util.Collections;
import java.util.List;
@ -239,18 +239,18 @@ public final class ModConfig {
}
try {
for (String s : this.plantBoostExceptions.get())
PlantBoostEffect.EXCEPTIONS.add(Objects.requireNonNull(ForgeRegistries.BLOCKS.getValue(new ResourceLocation(s))));
for (var s : this.plantBoostExceptions.get())
PlantBoostEffect.EXCEPTIONS.add(Objects.requireNonNull(BuiltInRegistries.BLOCK.get(new ResourceLocation(s))));
} catch (Exception e) {
NaturesAura.LOGGER.warn("Error parsing plantBoostExceptions", e);
}
try {
for (String s : this.additionalProjectiles.get()) {
for (var s : this.additionalProjectiles.get()) {
var split = s.split("->");
var name = new ResourceLocation(split[0]);
var type = Objects.requireNonNull(ForgeRegistries.ENTITY_TYPES.getValue(name));
var type = Objects.requireNonNull(BuiltInRegistries.ENTITY_TYPE.get(name));
var amount = Integer.parseInt(split[1]);
NaturesAuraAPI.PROJECTILE_GENERATIONS.put(type, amount);
}
@ -258,4 +258,5 @@ public final class ModConfig {
NaturesAura.LOGGER.warn("Error parsing additionalProjectiles", e);
}
}
}

View file

@ -6,18 +6,17 @@ import de.ellpeck.naturesaura.blocks.multi.Multiblocks;
import de.ellpeck.naturesaura.chunk.effect.DrainSpotEffects;
import de.ellpeck.naturesaura.compat.Compat;
import de.ellpeck.naturesaura.events.CommonEvents;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.proxy.ClientProxy;
import de.ellpeck.naturesaura.proxy.IProxy;
import de.ellpeck.naturesaura.proxy.ServerProxy;
import de.ellpeck.naturesaura.recipes.ModRecipes;
import net.neoforged.neoforge.common.ModConfigSpec;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.fml.DistExecutor;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.fml.javafmlmod.FMLJavaModLoadingContext;
import net.neoforged.fml.loading.FMLEnvironment;
import net.neoforged.neoforge.common.ModConfigSpec;
import net.neoforged.neoforge.common.NeoForge;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -29,13 +28,13 @@ public final class NaturesAura {
public static final Logger LOGGER = LogManager.getLogger(NaturesAura.MOD_NAME);
public static NaturesAura instance;
// this causes a classloading issue if it's not wrapped like this
@SuppressWarnings("Convert2MethodRef")
public static IProxy proxy = DistExecutor.unsafeRunForDist(() -> () -> new ClientProxy(), () -> () -> new ServerProxy());
public static IProxy proxy;
public NaturesAura() {
public NaturesAura(IEventBus eventBus) {
NaturesAura.instance = this;
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
NaturesAura.proxy = FMLEnvironment.dist.isClient() ? new ClientProxy() : new ServerProxy();
eventBus.addListener(this::setup);
var builder = new ModConfigSpec.Builder();
ModConfig.instance = new ModConfig(builder);
@ -50,7 +49,6 @@ public final class NaturesAura {
private void preInit(FMLCommonSetupEvent event) {
Compat.setup(event);
PacketHandler.init();
new Multiblocks();
NeoForge.EVENT_BUS.register(new CommonEvents());

View file

@ -2,6 +2,7 @@ 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;
@ -14,6 +15,7 @@ import de.ellpeck.naturesaura.api.misc.WeightedOre;
import de.ellpeck.naturesaura.api.multiblock.IMultiblock;
import de.ellpeck.naturesaura.api.multiblock.Matcher;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Tuple;
import net.minecraft.world.entity.EntityType;
@ -23,10 +25,9 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.common.capabilities.*;
import net.neoforged.neoforge.common.capabilities.CapabilityToken;
import net.neoforged.neoforge.common.capabilities.Capability;
import net.neoforged.neoforge.common.capabilities.CapabilityManager;
import net.neoforged.neoforge.attachment.AttachmentType;
import net.neoforged.neoforge.capabilities.BlockCapability;
import net.neoforged.neoforge.capabilities.ItemCapability;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
@ -84,25 +85,21 @@ public final class NaturesAuraAPI {
*/
public static final Map<ItemStack, WeatherType> WEATHER_CHANGER_CONVERSIONS = new HashMap<>();
/**
* The capability for any item or block that stores Aura in the form of an {@link IAuraContainer}
* The capability for any item that stores Aura in the form of an {@link IAuraContainer}
*/
public static final Capability<IAuraContainer> CAP_AURA_CONTAINER = CapabilityManager.get(new CapabilityToken<>() {
});
public static final ItemCapability<IAuraContainer, Void> AURA_CONTAINER_ITEM_CAPABILITY = ItemCapability.createVoid(new ResourceLocation(NaturesAuraAPI.MOD_ID, "aura_container_item"), IAuraContainer.class);
/**
* The capability for any block that stores Aura in the form of an {@link IAuraContainer}
*/
public static final BlockCapability<IAuraContainer, Direction> AURA_CONTAINER_BLOCK_CAPABILITY = BlockCapability.create(new ResourceLocation(NaturesAuraAPI.MOD_ID, "aura_container_block"), IAuraContainer.class, Direction.class);
/**
* The capability for any item that can be recharged from an Aura storage container like the Aura Cache in the form of {@link IAuraRecharge} by a player holding it in their hand
*/
public static final Capability<IAuraRecharge> CAP_AURA_RECHARGE = CapabilityManager.get(new CapabilityToken<>() {
});
public static final ItemCapability<IAuraRecharge, Void> AURA_RECHARGE_CAPABILITY = ItemCapability.createVoid(new ResourceLocation(NaturesAuraAPI.MOD_ID, "aura_recharge"), IAuraRecharge.class);
/**
* 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 Capability<IAuraChunk> CAP_AURA_CHUNK = CapabilityManager.get(new CapabilityToken<>() {
});
/**
* The capability that any level has to store Nature's Aura specific data in it. To retrieve this capability from any level, use the helper methods {@link ILevelData#getLevelData(net.minecraft.world.level.Level)} or {@link ILevelData#getOverworldData(net.minecraft.world.level.Level)}.
*/
public static final Capability<ILevelData> CAP_LEVEL_DATA = CapabilityManager.get(new CapabilityToken<>() {
});
public static final AttachmentType<AuraChunkProvider> AURA_CHUNK_ATTACHMENT = AttachmentType.serializable(AuraChunkProvider::new).build();
private static final IInternalHooks INSTANCE;
static {
@ -260,6 +257,11 @@ public final class NaturesAuraAPI {
* @see IAuraChunk#getHighestSpot(Level, BlockPos, int, BlockPos)
*/
BlockPos getHighestAuraDrainSpot(Level level, BlockPos pos, int radius, BlockPos defaultSpot);
ILevelData getLevelData(Level level);
IAuraChunk createAuraChunk();
}
}

View file

@ -0,0 +1,29 @@
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.getCapability(NaturesAuraAPI.CAP_AURA_CHUNK, null).orElse(null);
return chunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT).get(chunk);
}
/**
@ -159,4 +159,7 @@ public interface IAuraChunk extends INBTSerializable<CompoundTag> {
IAuraType getType();
void markDirty();
void ensureInitialized(LevelChunk chunk);
}

View file

@ -1,16 +1,13 @@
package de.ellpeck.naturesaura.api.misc;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.common.util.INBTSerializable;
import net.neoforged.neoforge.items.IItemHandlerModifiable;
import net.neoforged.neoforge.common.capabilities.ICapabilityProvider;
public interface ILevelData extends ICapabilityProvider, INBTSerializable<CompoundTag> {
public interface ILevelData {
static ILevelData getLevelData(Level level) {
return level.getCapability(NaturesAuraAPI.CAP_LEVEL_DATA, null).orElse(null);
return NaturesAuraAPI.instance().getLevelData(level);
}
static ILevelData getOverworldData(Level level) {
@ -22,4 +19,5 @@ public interface ILevelData extends ICapabilityProvider, INBTSerializable<Compou
IItemHandlerModifiable getEnderStorage(String name);
boolean isEnderStorageLocked(String name);
}

View file

@ -53,7 +53,8 @@ public class BlockAncientLeaves extends LeavesBlock implements IModItem, IColorP
if (rand.nextFloat() >= 0.95F && !levelIn.getBlockState(pos.below()).isCollisionShapeFullBlock(levelIn, pos)) {
var tile = levelIn.getBlockEntity(pos);
if (tile instanceof BlockEntityAncientLeaves) {
if (((BlockEntityAncientLeaves) tile).getAuraContainer().getStoredAura() > 0) {
var container = levelIn.getCapability(NaturesAuraAPI.AURA_CONTAINER_BLOCK_CAPABILITY, tile.getBlockPos(), tile.getBlockState(), tile, null);
if (container.getStoredAura() > 0) {
NaturesAuraAPI.instance().spawnMagicParticle(
pos.getX() + rand.nextDouble(), pos.getY(), pos.getZ() + rand.nextDouble(),
0F, 0F, 0F, 0xCC4780,
@ -72,7 +73,8 @@ public class BlockAncientLeaves extends LeavesBlock implements IModItem, IColorP
if (!levelIn.isClientSide) {
var tile = levelIn.getBlockEntity(pos);
if (tile instanceof BlockEntityAncientLeaves) {
if (((BlockEntityAncientLeaves) tile).getAuraContainer().getStoredAura() <= 0) {
var container = levelIn.getCapability(NaturesAuraAPI.AURA_CONTAINER_BLOCK_CAPABILITY, tile.getBlockPos(), tile.getBlockState(), tile, null);
if (container.getStoredAura() <= 0) {
levelIn.setBlockAndUpdate(pos, ModBlocks.DECAYED_LEAVES.defaultBlockState());
}
}
@ -94,4 +96,5 @@ public class BlockAncientLeaves extends LeavesBlock implements IModItem, IColorP
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
return new BlockEntityAncientLeaves(pos, state);
}
}

View file

@ -1,5 +1,6 @@
package de.ellpeck.naturesaura.blocks;
import com.mojang.serialization.MapCodec;
import de.ellpeck.naturesaura.data.BlockStateGenerator;
import de.ellpeck.naturesaura.data.ItemModelGenerator;
import de.ellpeck.naturesaura.gen.ModFeatures;
@ -61,7 +62,7 @@ public class BlockAncientSapling extends BushBlock implements BonemealableBlock,
}
@Override
public boolean isValidBonemealTarget(LevelReader p_256559_, BlockPos p_50898_, BlockState p_50899_, boolean p_50900_) {
public boolean isValidBonemealTarget(LevelReader pLevel, BlockPos pPos, BlockState pState) {
return true;
}
@ -89,4 +90,10 @@ public class BlockAncientSapling extends BushBlock implements BonemealableBlock,
public void generateCustomItemModel(ItemModelGenerator generator) {
generator.withExistingParent(this.getBaseName(), "item/generated").texture("layer0", "block/" + this.getBaseName());
}
@Override
protected MapCodec<? extends BushBlock> codec() {
return null;
}
}

View file

@ -21,7 +21,7 @@ public class BlockAnimalContainer extends BlockContainerImpl implements IVisuali
private static final VoxelShape SHAPE = Block.box(5, 0, 5, 11, 13, 11);
public BlockAnimalContainer() {
super("animal_container", BlockEntityAnimalContainer.class, Properties.copy(Blocks.STONE));
super("animal_container", BlockEntityAnimalContainer.class, Properties.ofFullCopy(Blocks.STONE));
}
@Override
@ -57,4 +57,5 @@ public class BlockAnimalContainer extends BlockContainerImpl implements IVisuali
public void generateCustomBlockState(BlockStateGenerator generator) {
generator.simpleBlock(this, generator.models().getExistingFile(generator.modLoc(this.getBaseName())));
}
}

View file

@ -1,5 +1,6 @@
package de.ellpeck.naturesaura.blocks;
import com.mojang.serialization.MapCodec;
import de.ellpeck.naturesaura.blocks.tiles.BlockEntityAuraBloom;
import de.ellpeck.naturesaura.blocks.tiles.ITickableBlockEntity;
import de.ellpeck.naturesaura.blocks.tiles.ModBlockEntities;
@ -47,6 +48,11 @@ public class BlockAuraBloom extends BushBlock implements IModItem, ICustomBlockS
return this.mayPlaceOn(levelIn.getBlockState(down), levelIn, down);
}
@Override
protected MapCodec<? extends BushBlock> codec() {
return null;
}
@Override
protected boolean mayPlaceOn(BlockState state, BlockGetter levelIn, BlockPos pos) {
return Arrays.stream(this.allowedGround).anyMatch(state::is);
@ -92,4 +98,5 @@ public class BlockAuraBloom extends BushBlock implements IModItem, ICustomBlockS
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) {
return ITickableBlockEntity.createTickerHelper(type, ModBlockEntities.AURA_BLOOM);
}
}

View file

@ -31,7 +31,7 @@ public class BlockAuraTimer extends BlockContainerImpl implements ICustomBlockSt
private static final VoxelShape SHAPE = Block.box(1, 0, 1, 15, 15, 15);
public BlockAuraTimer() {
super("aura_timer", BlockEntityAuraTimer.class, Properties.copy(Blocks.SMOOTH_STONE));
super("aura_timer", BlockEntityAuraTimer.class, Properties.ofFullCopy(Blocks.SMOOTH_STONE));
this.registerDefaultState(this.defaultBlockState().setValue(BlockStateProperties.POWERED, false));
}

View file

@ -22,7 +22,7 @@ public class BlockBlastFurnaceBooster extends BlockContainerImpl implements ICus
private static final VoxelShape SHAPE = Shapes.create(1 / 16F, 0, 1 / 16F, 15 / 16F, 1, 15 / 16F);
public BlockBlastFurnaceBooster() {
super("blast_furnace_booster", BlockEntityBlastFurnaceBooster.class, Block.Properties.copy(Blocks.BLAST_FURNACE).lightLevel(s -> 0));
super("blast_furnace_booster", BlockEntityBlastFurnaceBooster.class, Block.Properties.ofFullCopy(Blocks.BLAST_FURNACE).lightLevel(s -> 0));
}
@Override

View file

@ -8,7 +8,7 @@ import net.minecraft.world.level.block.Blocks;
public class BlockChorusGenerator extends BlockContainerImpl implements ICustomBlockState {
public BlockChorusGenerator() {
super("chorus_generator", BlockEntityChorusGenerator.class, Properties.copy(Blocks.END_STONE));
super("chorus_generator", BlockEntityChorusGenerator.class, Properties.ofFullCopy(Blocks.END_STONE));
}
@Override

View file

@ -1,5 +1,6 @@
package de.ellpeck.naturesaura.blocks;
import com.mojang.serialization.MapCodec;
import de.ellpeck.naturesaura.blocks.tiles.BlockEntityImpl;
import de.ellpeck.naturesaura.blocks.tiles.ITickableBlockEntity;
import de.ellpeck.naturesaura.reg.IModItem;
@ -106,6 +107,11 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
return this.baseName;
}
@Override
protected MapCodec<? extends BaseEntityBlock> codec() {
return null;
}
@Override
public RenderShape getRenderShape(BlockState state) {
return RenderShape.MODEL;
@ -129,11 +135,11 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
}
@Override
public void playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) {
public BlockState playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) {
var tile = level.getBlockEntity(pos);
if (tile instanceof BlockEntityImpl impl)
impl.dropInventory();
super.playerWillDestroy(level, pos, state, player);
return super.playerWillDestroy(level, pos, state, player);
}
@Override
@ -181,4 +187,5 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
throw new IllegalStateException("Cannot construct block entity from class " + this.tileClass, e);
}
}
}

View file

@ -1,5 +1,6 @@
package de.ellpeck.naturesaura.blocks;
import com.mojang.serialization.MapCodec;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.data.BlockStateGenerator;
import de.ellpeck.naturesaura.data.ItemModelGenerator;
@ -49,7 +50,7 @@ public class BlockDimensionRail extends BaseRailBlock implements IModItem, ICust
@SafeVarargs
public BlockDimensionRail(String name, ResourceKey<Level> goalDim, ResourceKey<Level>... canUseDims) {
super(false, Properties.copy(Blocks.RAIL));
super(false, Properties.ofFullCopy(Blocks.RAIL));
this.name = name;
this.goalDim = goalDim;
this.canUseDims = canUseDims;
@ -136,6 +137,11 @@ public class BlockDimensionRail extends BaseRailBlock implements IModItem, ICust
}
}
@Override
protected MapCodec<? extends BaseRailBlock> codec() {
return null;
}
@Override
@SuppressWarnings({"deprecation", "RedundantSuppression"})
public Property<RailShape> getShapeProperty() {

View file

@ -1,5 +1,6 @@
package de.ellpeck.naturesaura.blocks;
import com.mojang.serialization.MapCodec;
import de.ellpeck.naturesaura.blocks.tiles.BlockEntityEndFlower;
import de.ellpeck.naturesaura.blocks.tiles.ITickableBlockEntity;
import de.ellpeck.naturesaura.blocks.tiles.ModBlockEntities;
@ -70,6 +71,11 @@ public class BlockEndFlower extends BushBlock implements IModItem, ICustomBlockS
}
}
@Override
protected MapCodec<? extends BushBlock> codec() {
return null;
}
@Override
public boolean canSurvive(BlockState state, LevelReader levelIn, BlockPos pos) {
return levelIn.getBlockState(pos.below()).getBlock() == Blocks.END_STONE;

View file

@ -33,7 +33,6 @@ import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.AnvilUpdateEvent;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.neoforge.network.NetworkHooks;
import javax.annotation.Nullable;
import java.util.List;
@ -92,7 +91,7 @@ public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider
var tile = levelIn.getBlockEntity(pos);
if (tile instanceof BlockEntityEnderCrate crate && crate.canOpen() && crate.canUseRightNow(2500)) {
crate.drainAura(2500);
NetworkHooks.openScreen((ServerPlayer) player, crate, pos);
player.openMenu(crate, pos);
}
}
return InteractionResult.SUCCESS;
@ -132,4 +131,5 @@ public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider
public void registerTESR() {
BlockEntityRenderers.register(ModBlockEntities.ENDER_CRATE, RenderEnderCrate::new);
}
}

View file

@ -5,9 +5,9 @@ import de.ellpeck.naturesaura.reg.ICustomBlockState;
import de.ellpeck.naturesaura.reg.IModItem;
import de.ellpeck.naturesaura.reg.INoItemBlock;
import de.ellpeck.naturesaura.reg.ModRegistry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.FlowerPotBlock;
import net.neoforged.neoforge.registries.ForgeRegistries;
import java.util.function.Supplier;
@ -20,12 +20,12 @@ public class BlockFlowerPot extends FlowerPotBlock implements ICustomBlockState,
@Override
public void generateCustomBlockState(BlockStateGenerator generator) {
generator.simpleBlock(this, generator.models().withExistingParent(this.getBaseName(), "block/flower_pot_cross").texture("plant", "block/" + ForgeRegistries.BLOCKS.getKey(this.getContent()).getPath()).renderType("cutout"));
generator.simpleBlock(this, generator.models().withExistingParent(this.getBaseName(), "block/flower_pot_cross").texture("plant", "block/" + BuiltInRegistries.BLOCK.getKey(this.getPotted()).getPath()).renderType("cutout"));
}
@Override
public String getBaseName() {
return "potted_" + ForgeRegistries.BLOCKS.getKey(this.getContent()).getPath();
return "potted_" + BuiltInRegistries.BLOCK.getKey(this.getPotted()).getPath();
}
}

View file

@ -34,7 +34,7 @@ public class BlockGoldPowder extends BlockImpl implements IColorProvidingBlock,
protected static final VoxelShape[] SHAPES = {Block.box(3.0D, 0.0D, 3.0D, 13.0D, 1.0D, 13.0D), Block.box(3.0D, 0.0D, 3.0D, 13.0D, 1.0D, 16.0D), Block.box(0.0D, 0.0D, 3.0D, 13.0D, 1.0D, 13.0D), Block.box(0.0D, 0.0D, 3.0D, 13.0D, 1.0D, 16.0D), Block.box(3.0D, 0.0D, 0.0D, 13.0D, 1.0D, 13.0D), Block.box(3.0D, 0.0D, 0.0D, 13.0D, 1.0D, 16.0D), Block.box(0.0D, 0.0D, 0.0D, 13.0D, 1.0D, 13.0D), Block.box(0.0D, 0.0D, 0.0D, 13.0D, 1.0D, 16.0D), Block.box(3.0D, 0.0D, 3.0D, 16.0D, 1.0D, 13.0D), Block.box(3.0D, 0.0D, 3.0D, 16.0D, 1.0D, 16.0D), Block.box(0.0D, 0.0D, 3.0D, 16.0D, 1.0D, 13.0D), Block.box(0.0D, 0.0D, 3.0D, 16.0D, 1.0D, 16.0D), Block.box(3.0D, 0.0D, 0.0D, 16.0D, 1.0D, 13.0D), Block.box(3.0D, 0.0D, 0.0D, 16.0D, 1.0D, 16.0D), Block.box(0.0D, 0.0D, 0.0D, 16.0D, 1.0D, 13.0D), Block.box(0.0D, 0.0D, 0.0D, 16.0D, 1.0D, 16.0D)};
public BlockGoldPowder() {
super("gold_powder", Properties.copy(Blocks.REDSTONE_WIRE));
super("gold_powder", Properties.ofFullCopy(Blocks.REDSTONE_WIRE));
this.registerDefaultState(this.defaultBlockState().setValue(BlockGoldPowder.NORTH, RedstoneSide.NONE).setValue(BlockGoldPowder.EAST, RedstoneSide.NONE).setValue(BlockGoldPowder.SOUTH, RedstoneSide.NONE).setValue(BlockGoldPowder.WEST, RedstoneSide.NONE));
}

View file

@ -27,6 +27,7 @@ import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.items.IItemHandler;
import javax.annotation.Nullable;
@ -122,7 +123,7 @@ public class BlockGratedChute extends BlockContainerImpl implements ICustomBlock
public int getAnalogOutputSignal(BlockState blockState, Level levelIn, BlockPos pos) {
var tile = levelIn.getBlockEntity(pos);
if (tile instanceof BlockEntityGratedChute) {
IItemHandler handler = ((BlockEntityGratedChute) tile).getItemHandler();
var handler = levelIn.getCapability(Capabilities.ItemHandler.BLOCK, tile.getBlockPos(), tile.getBlockState(), tile, null);
var stack = handler.getStackInSlot(0);
if (stack.isEmpty())
return 0;
@ -146,4 +147,5 @@ public class BlockGratedChute extends BlockContainerImpl implements ICustomBlock
public void generateCustomItemModel(ItemModelGenerator generator) {
generator.withExistingParent(this.getBaseName(), generator.modLoc("block/" + this.getBaseName() + "_down"));
}
}

View file

@ -15,7 +15,7 @@ import net.minecraft.world.phys.BlockHitResult;
public class BlockItemDistributor extends BlockContainerImpl implements ICustomBlockState {
public BlockItemDistributor() {
super("item_distributor", BlockEntityItemDistributor.class, Properties.copy(Blocks.STONE_BRICKS));
super("item_distributor", BlockEntityItemDistributor.class, Properties.ofFullCopy(Blocks.STONE_BRICKS));
}
@Override

View file

@ -15,7 +15,7 @@ import net.minecraft.world.level.block.state.BlockState;
public class BlockNetherGrass extends BlockImpl implements ICustomBlockState, BonemealableBlock {
public BlockNetherGrass() {
super("nether_grass", Properties.copy(Blocks.NETHERRACK).randomTicks());
super("nether_grass", Properties.ofFullCopy(Blocks.NETHERRACK).randomTicks());
}
@Override
@ -36,7 +36,7 @@ public class BlockNetherGrass extends BlockImpl implements ICustomBlockState, Bo
}
@Override
public boolean isValidBonemealTarget(LevelReader levelIn, BlockPos pos, BlockState state, boolean isClient) {
public boolean isValidBonemealTarget(LevelReader levelIn, BlockPos pos, BlockState state) {
return levelIn.getBlockState(pos.above()).isAir();
}
@ -48,7 +48,7 @@ public class BlockNetherGrass extends BlockImpl implements ICustomBlockState, Bo
@Override
public void performBonemeal(ServerLevel level, RandomSource rand, BlockPos pos, BlockState state) {
var blockpos = pos.above();
var blockstate = Blocks.GRASS.defaultBlockState();
var blockstate = Blocks.GRASS_BLOCK.defaultBlockState();
for (var i = 0; i < 128; ++i) {
var blockpos1 = blockpos;
@ -81,4 +81,5 @@ public class BlockNetherGrass extends BlockImpl implements ICustomBlockState, Bo
}
}
}

View file

@ -19,7 +19,7 @@ import net.neoforged.bus.api.SubscribeEvent;
public class BlockSlimeSplitGenerator extends BlockContainerImpl implements IVisualizable, ICustomBlockState {
public BlockSlimeSplitGenerator() {
super("slime_split_generator", BlockEntitySlimeSplitGenerator.class, Properties.copy(Blocks.SLIME_BLOCK).strength(2));
super("slime_split_generator", BlockEntitySlimeSplitGenerator.class, Properties.ofFullCopy(Blocks.SLIME_BLOCK).strength(2));
NeoForge.EVENT_BUS.register(new Events());
}

View file

@ -14,7 +14,7 @@ import net.neoforged.api.distmarker.OnlyIn;
public class BlockSnowCreator extends BlockContainerImpl implements IVisualizable, ICustomBlockState {
public BlockSnowCreator() {
super("snow_creator", BlockEntitySnowCreator.class, Properties.copy(Blocks.STONE_BRICKS));
super("snow_creator", BlockEntitySnowCreator.class, Properties.ofFullCopy(Blocks.STONE_BRICKS));
}
@Override

View file

@ -21,13 +21,14 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluids;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
public class BlockSpring extends BlockContainerImpl implements ICustomBlockState, IColorProvidingBlock, IColorProvidingItem, BucketPickup {
public BlockSpring() {
super("spring", BlockEntitySpring.class, Properties.copy(Blocks.STONE_BRICKS));
super("spring", BlockEntitySpring.class, Properties.ofFullCopy(Blocks.STONE_BRICKS));
}
@Override
@ -57,8 +58,8 @@ public class BlockSpring extends BlockContainerImpl implements ICustomBlockState
}
@Override
public ItemStack pickupBlock(LevelAccessor levelIn, BlockPos pos, BlockState state) {
if (levelIn.getBlockEntity(pos) instanceof BlockEntitySpring spring && spring.tryConsumeAura(2500))
public ItemStack pickupBlock(@Nullable Player pPlayer, LevelAccessor pLevel, BlockPos pPos, BlockState pState) {
if (pLevel.getBlockEntity(pPos) instanceof BlockEntitySpring spring && spring.tryConsumeAura(2500))
return new ItemStack(Items.WATER_BUCKET);
return ItemStack.EMPTY;
}
@ -68,4 +69,5 @@ public class BlockSpring extends BlockContainerImpl implements ICustomBlockState
public Optional<SoundEvent> getPickupSound() {
return Fluids.WATER.getPickupSound();
}
}

View file

@ -8,7 +8,7 @@ import net.minecraft.world.level.block.Blocks;
public class BlockWeatherChanger extends BlockContainerImpl implements ICustomBlockState {
public BlockWeatherChanger() {
super("weather_changer", BlockEntityWeatherChanger.class, Properties.copy(Blocks.STONE_BRICKS));
super("weather_changer", BlockEntityWeatherChanger.class, Properties.ofFullCopy(Blocks.STONE_BRICKS));
}
@Override

View file

@ -62,8 +62,8 @@ public class BlockWoodStand extends BlockContainerImpl implements ITESRProvider<
var saplingStack = new ItemStack(level.getBlockState(pos).getBlock());
if (!saplingStack.isEmpty()) {
for (var recipe : ((Level) level).getRecipeManager().getRecipesFor(ModRecipes.TREE_RITUAL_TYPE, null, (Level) level)) {
if (recipe.saplingType.test(saplingStack)) {
List<Ingredient> required = new ArrayList<>(Arrays.asList(recipe.ingredients));
if (recipe.value().saplingType.test(saplingStack)) {
List<Ingredient> required = new ArrayList<>(recipe.value().ingredients);
var toPick = new MutableObject<BlockEntityWoodStand>();
var fine = Multiblocks.TREE_RITUAL.forEach(pos, 'W', (tilePos, matcher) -> {
@ -89,7 +89,7 @@ public class BlockWoodStand extends BlockContainerImpl implements ITESRProvider<
});
if (fine && required.isEmpty()) {
toPick.getValue().setRitual(pos, recipe);
toPick.getValue().setRitual(pos, recipe.value());
break;
}
}

View file

@ -42,7 +42,7 @@ public final class Multiblocks {
// try-catch to prevent blocks that need to have been placed crashing here
try {
var stack = new ItemStack(state.getBlock());
return !stack.isEmpty() && level.getRecipeManager().getRecipesFor(ModRecipes.TREE_RITUAL_TYPE, null, level).stream().anyMatch(r -> r.saplingType.test(stack));
return !stack.isEmpty() && level.getRecipeManager().getRecipesFor(ModRecipes.TREE_RITUAL_TYPE, null, level).stream().anyMatch(r -> r.value().saplingType.test(stack));
} catch (Exception e) {
return false;
}
@ -99,4 +99,5 @@ public final class Multiblocks {
'R', Blocks.REDSTONE_BLOCK,
'0', ModBlocks.RF_CONVERTER,
' ', Matcher.any());
}

View file

@ -1,7 +1,6 @@
package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.container.IAuraContainer;
import de.ellpeck.naturesaura.api.aura.container.NaturalAuraContainer;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
@ -9,7 +8,7 @@ import net.minecraft.world.level.block.state.BlockState;
public class BlockEntityAncientLeaves extends BlockEntityImpl {
private final NaturalAuraContainer container = new NaturalAuraContainer(NaturesAuraAPI.TYPE_OVERWORLD, 2000, 500) {
public final NaturalAuraContainer container = new NaturalAuraContainer(NaturesAuraAPI.TYPE_OVERWORLD, 2000, 500) {
@Override
public int getAuraColor() {
return 0xCE5489;
@ -29,11 +28,6 @@ public class BlockEntityAncientLeaves extends BlockEntityImpl {
super(ModBlockEntities.ANCIENT_LEAVES, pos, state);
}
@Override
public IAuraContainer getAuraContainer() {
return this.container;
}
@Override
public void writeNBT(CompoundTag compound, SaveType type) {
super.writeNBT(compound, type);

View file

@ -16,6 +16,7 @@ import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
@ -25,7 +26,7 @@ import java.util.List;
public class BlockEntityAnimalSpawner extends BlockEntityImpl implements ITickableBlockEntity {
private AnimalSpawnerRecipe currentRecipe;
private RecipeHolder<AnimalSpawnerRecipe> currentRecipe;
private double spawnX;
private double spawnZ;
private int time;
@ -50,7 +51,7 @@ public class BlockEntityAnimalSpawner extends BlockEntityImpl implements ITickab
}
if (this.currentRecipe != null) {
var drain = Mth.ceil(this.currentRecipe.aura / (float) this.currentRecipe.time * 10F);
var drain = Mth.ceil(this.currentRecipe.value().aura / (float) this.currentRecipe.value().time * 10F);
if (!this.canUseRightNow(drain))
return;
@ -58,8 +59,8 @@ public class BlockEntityAnimalSpawner extends BlockEntityImpl implements ITickab
IAuraChunk.getAuraChunk(this.level, spot).drainAura(spot, drain);
this.time += 10;
if (this.time >= this.currentRecipe.time) {
var entity = this.currentRecipe.makeEntity(this.level, BlockPos.containing(this.spawnX, this.worldPosition.getY() + 1, this.spawnZ));
if (this.time >= this.currentRecipe.value().time) {
var entity = this.currentRecipe.value().makeEntity(this.level, BlockPos.containing(this.spawnX, this.worldPosition.getY() + 1, this.spawnZ));
this.level.addFreshEntity(entity);
this.currentRecipe = null;
@ -71,9 +72,9 @@ public class BlockEntityAnimalSpawner extends BlockEntityImpl implements ITickab
new AABB(this.worldPosition).inflate(2));
for (var recipe : this.level.getRecipeManager().getRecipesFor(ModRecipes.ANIMAL_SPAWNER_TYPE, null, this.level)) {
if (recipe.ingredients.length != items.size())
if (recipe.value().ingredients.size() != items.size())
continue;
List<Ingredient> required = new ArrayList<>(Arrays.asList(recipe.ingredients));
List<Ingredient> required = new ArrayList<>(recipe.value().ingredients);
for (var item : items) {
if (!item.isAlive() || item.hasPickUpDelay())
break;
@ -123,7 +124,7 @@ public class BlockEntityAnimalSpawner extends BlockEntityImpl implements ITickab
this.level.random.nextFloat() + 0.5F);
if (this.entityClient == null) {
this.entityClient = this.currentRecipe.makeEntity(this.level, BlockPos.ZERO);
this.entityClient = this.currentRecipe.value().makeEntity(this.level, BlockPos.ZERO);
this.entityClient.setPos(this.spawnX, this.worldPosition.getY() + 1, this.spawnZ);
}
var bounds = this.entityClient.getBoundingBox();
@ -141,7 +142,7 @@ public class BlockEntityAnimalSpawner extends BlockEntityImpl implements ITickab
super.writeNBT(compound, type);
if (type != SaveType.BLOCK) {
if (this.currentRecipe != null) {
compound.putString("recipe", this.currentRecipe.name.toString());
compound.putString("recipe", this.currentRecipe.id().toString());
compound.putDouble("spawn_x", this.spawnX);
compound.putDouble("spawn_z", this.spawnZ);
compound.putInt("time", this.time);
@ -149,6 +150,7 @@ public class BlockEntityAnimalSpawner extends BlockEntityImpl implements ITickab
}
}
@SuppressWarnings("unchecked")
@Override
public void readNBT(CompoundTag compound, SaveType type) {
super.readNBT(compound, type);
@ -156,7 +158,7 @@ public class BlockEntityAnimalSpawner extends BlockEntityImpl implements ITickab
if (compound.contains("recipe")) {
if (this.hasLevel()) {
var name = new ResourceLocation(compound.getString("recipe"));
this.currentRecipe = (AnimalSpawnerRecipe) this.level.getRecipeManager().byKey(name).orElse(null);
this.currentRecipe = (RecipeHolder<AnimalSpawnerRecipe>) this.level.getRecipeManager().byKey(name).orElse(null);
}
this.spawnX = compound.getDouble("spawn_x");
this.spawnZ = compound.getDouble("spawn_z");
@ -172,4 +174,5 @@ public class BlockEntityAnimalSpawner extends BlockEntityImpl implements ITickab
public boolean allowsLowerLimiter() {
return true;
}
}

View file

@ -12,7 +12,6 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.neoforged.neoforge.items.IItemHandlerModifiable;
import java.util.Map;
@ -22,7 +21,7 @@ public class BlockEntityAuraTimer extends BlockEntityImpl implements ITickableBl
.put(NaturesAuraAPI.TYPE_OVERWORLD, 20)
.put(NaturesAuraAPI.TYPE_NETHER, 20 * 60)
.put(NaturesAuraAPI.TYPE_END, 20 * 60 * 60).build();
private final ItemStackHandlerNA itemHandler = new ItemStackHandlerNA(1, this, true) {
public final ItemStackHandlerNA itemHandler = new ItemStackHandlerNA(1, this, true) {
@Override
protected boolean canInsert(ItemStack stack, int slot) {
return stack.getItem() == ModItems.AURA_BOTTLE;
@ -98,11 +97,6 @@ public class BlockEntityAuraTimer extends BlockEntityImpl implements ITickableBl
return this.timer / (float) this.getTotalTime();
}
@Override
public IItemHandlerModifiable getItemHandler() {
return this.itemHandler;
}
@Override
public void writeNBT(CompoundTag compound, SaveType type) {
super.writeNBT(compound, type);

View file

@ -82,7 +82,7 @@ public class BlockEntityAutoCrafter extends BlockEntityImpl implements ITickable
if (recipe == null)
return;
var result = recipe.assemble(this.crafting, this.level.registryAccess());
var result = recipe.value().assemble(this.crafting, this.level.registryAccess());
if (result.isEmpty())
return;
var resultItem = new ItemEntity(this.level,
@ -90,7 +90,7 @@ public class BlockEntityAutoCrafter extends BlockEntityImpl implements ITickable
resultItem.setDeltaMovement(0, 0, 0);
this.level.addFreshEntity(resultItem);
var remainingItems = recipe.getRemainingItems(this.crafting);
var remainingItems = recipe.value().getRemainingItems(this.crafting);
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item == null)

View file

@ -10,8 +10,8 @@ import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.level.block.entity.BlastFurnaceBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.common.Tags;
import net.neoforged.neoforge.common.capabilities.Capabilities;
import net.neoforged.neoforge.items.IItemHandlerModifiable;
import javax.annotation.Nonnull;
@ -35,7 +35,7 @@ public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements I
var below = this.level.getBlockEntity(this.worldPosition.below());
if (!(below instanceof BlastFurnaceBlockEntity tile))
return;
Recipe<?> recipe = this.level.getRecipeManager().getRecipeFor(BlockEntityFurnaceHeater.getRecipeType(tile), tile, this.level).orElse(null);
Recipe<?> recipe = this.level.getRecipeManager().getRecipeFor(BlockEntityFurnaceHeater.getRecipeType(tile), tile, this.level).orElse(null).value();
if (recipe == null)
return;
if (!this.isApplicable(recipe.getIngredients()))
@ -80,12 +80,11 @@ public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements I
return false;
}
@Override
public IItemHandlerModifiable getItemHandler() {
var below = this.level.getBlockEntity(this.worldPosition.below());
if (!(below instanceof BlastFurnaceBlockEntity))
return null;
var handler = below.getCapability(Capabilities.ITEM_HANDLER, Direction.UP).orElse(null);
var handler = this.level.getCapability(Capabilities.ItemHandler.BLOCK, below.getBlockPos(), below.getBlockState(), below, Direction.UP);
if (handler == null)
return null;
return new IItemHandlerModifiable() {
@ -138,4 +137,5 @@ public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements I
public boolean allowsLowerLimiter() {
return true;
}
}

View file

@ -2,7 +2,6 @@ package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.container.BasicAuraContainer;
import de.ellpeck.naturesaura.api.aura.container.IAuraContainer;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.core.BlockPos;
@ -16,7 +15,7 @@ import net.minecraft.world.phys.AABB;
public class BlockEntityEndFlower extends BlockEntityImpl implements ITickableBlockEntity {
private final BasicAuraContainer container = new BasicAuraContainer(null, 500000) {
public final BasicAuraContainer container = new BasicAuraContainer(null, 500000) {
{
this.aura = this.maxAura;
}
@ -94,11 +93,6 @@ public class BlockEntityEndFlower extends BlockEntityImpl implements ITickableBl
}
}
@Override
public IAuraContainer getAuraContainer() {
return this.container;
}
@Override
public void writeNBT(CompoundTag compound, SaveType type) {
super.writeNBT(compound, type);
@ -116,4 +110,5 @@ public class BlockEntityEndFlower extends BlockEntityImpl implements ITickableBl
this.isDrainMode = compound.getBoolean("drain_mode");
}
}
}

View file

@ -24,7 +24,7 @@ import javax.annotation.Nullable;
public class BlockEntityEnderCrate extends BlockEntityImpl implements MenuProvider {
public String name;
private final IItemHandlerModifiable wrappedEnderStorage = new IItemHandlerModifiable() {
public final IItemHandlerModifiable wrappedEnderStorage = new IItemHandlerModifiable() {
@Override
public void setStackInSlot(int slot, @Nonnull ItemStack stack) {
this.getStorage().setStackInSlot(slot, stack);
@ -82,13 +82,6 @@ public class BlockEntityEnderCrate extends BlockEntityImpl implements MenuProvid
super(ModBlockEntities.ENDER_CRATE, pos, state);
}
@Override
public IItemHandlerModifiable getItemHandler() {
if (this.canOpen())
return this.wrappedEnderStorage;
return null;
}
public boolean canOpen() {
return this.name != null;
}
@ -149,11 +142,12 @@ public class BlockEntityEnderCrate extends BlockEntityImpl implements MenuProvid
@Nullable
@Override
public AbstractContainerMenu createMenu(int window, Inventory inv, Player player) {
return new ContainerEnderCrate(ModContainers.ENDER_CRATE, window, player, this.getItemHandler());
return new ContainerEnderCrate(ModContainers.ENDER_CRATE, window, player, this.wrappedEnderStorage);
}
@Override
public boolean allowsLowerLimiter() {
return true;
}
}

View file

@ -108,7 +108,7 @@ public class BlockEntityFieldCreator extends BlockEntityImpl implements ITickabl
var state = this.level.getBlockState(pos);
if (!state.isAir() && state.getDestroySpeed(this.level, pos) >= 0F) {
var fake = FakePlayerFactory.getMinecraft((ServerLevel) this.level);
if (!NeoForge.EVENT_BUS.post(new BlockEvent.BreakEvent(this.level, pos, state, fake))) {
if (!NeoForge.EVENT_BUS.post(new BlockEvent.BreakEvent(this.level, pos, state, fake)).isCanceled()) {
var drops = state.getDrops(new LootParams.Builder((ServerLevel) this.level)
.withParameter(LootContextParams.THIS_ENTITY, fake)
.withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos))
@ -208,4 +208,5 @@ public class BlockEntityFieldCreator extends BlockEntityImpl implements ITickabl
public boolean allowsLowerLimiter() {
return true;
}
}

View file

@ -7,12 +7,12 @@ import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticleStream;
import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.registries.ForgeRegistries;
import org.apache.commons.lang3.mutable.MutableInt;
import java.util.ArrayList;
@ -106,7 +106,7 @@ public class BlockEntityFlowerGenerator extends BlockEntityImpl implements ITick
var block = state.getBlock();
var tag = new CompoundTag();
tag.putString("block", ForgeRegistries.BLOCKS.getKey(block).toString());
tag.putString("block", BuiltInRegistries.BLOCK.getKey(block).toString());
tag.putInt("amount", entry.getValue().intValue());
list.add(tag);
}
@ -122,11 +122,12 @@ public class BlockEntityFlowerGenerator extends BlockEntityImpl implements ITick
var list = compound.getList("consumed_recently", 10);
for (var base : list) {
var tag = (CompoundTag) base;
var block = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(tag.getString("block")));
var block = BuiltInRegistries.BLOCK.get(new ResourceLocation(tag.getString("block")));
if (block != null)
this.consumedRecently.put(block.defaultBlockState(), new MutableInt(tag.getInt("amount")));
}
}
}
}

View file

@ -105,7 +105,7 @@ public class BlockEntityFurnaceHeater extends BlockEntityImpl implements ITickab
var recipe = this.level.getRecipeManager().getRecipeFor(BlockEntityFurnaceHeater.getRecipeType(furnace), furnace, this.level).orElse(null);
if (recipe == null)
return false;
var output = recipe.getResultItem(this.level.registryAccess());
var output = recipe.value().getResultItem(this.level.registryAccess());
var currOutput = furnace.getItem(2);
return currOutput.isEmpty() || Helper.areItemsEqual(currOutput, output, true) && currOutput.getCount() + output.getCount() <= output.getMaxStackSize();
} else

View file

@ -2,9 +2,6 @@ package de.ellpeck.naturesaura.blocks.tiles;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
public class BlockEntityGeneratorLimitRemover extends BlockEntityImpl {
@ -12,9 +9,4 @@ public class BlockEntityGeneratorLimitRemover extends BlockEntityImpl {
super(ModBlockEntities.GENERATOR_LIMIT_REMOVER, pos, state);
}
@Override
@OnlyIn(Dist.CLIENT)
public AABB getRenderBoundingBox() {
return new AABB(this.worldPosition, this.worldPosition.offset(1, 2, 1));
}
}

View file

@ -9,13 +9,12 @@ import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.neoforged.neoforge.common.capabilities.Capabilities;
import net.neoforged.neoforge.items.IItemHandlerModifiable;
import net.neoforged.neoforge.capabilities.Capabilities;
public class BlockEntityGratedChute extends BlockEntityImpl implements ITickableBlockEntity {
public boolean isBlacklist;
private final ItemStackHandlerNA items = new ItemStackHandlerNA(1, this, true) {
public final ItemStackHandlerNA items = new ItemStackHandlerNA(1, this, true) {
@Override
protected boolean canExtract(ItemStack stack, int slot, int amount) {
return BlockEntityGratedChute.this.redstonePower <= 0;
@ -48,7 +47,7 @@ public class BlockEntityGratedChute extends BlockEntityImpl implements ITickable
var tile = this.level.getBlockEntity(this.worldPosition.relative(facing));
if (tile == null)
break push;
var handler = tile.getCapability(Capabilities.ITEM_HANDLER, facing.getOpposite()).orElse(null);
var handler = this.level.getCapability(Capabilities.ItemHandler.BLOCK, tile.getBlockPos(), tile.getBlockState(), tile, facing.getOpposite());
if (handler == null)
break push;
for (var i = 0; i < handler.getSlots(); i++) {
@ -87,7 +86,7 @@ public class BlockEntityGratedChute extends BlockEntityImpl implements ITickable
var tileUp = this.level.getBlockEntity(this.worldPosition.above());
if (tileUp == null)
break pull;
var handlerUp = tileUp.getCapability(Capabilities.ITEM_HANDLER, Direction.DOWN).orElse(null);
var handlerUp = this.level.getCapability(Capabilities.ItemHandler.BLOCK, tileUp.getBlockPos(), tileUp.getBlockState(), tileUp, Direction.DOWN);
if (handlerUp == null)
break pull;
for (var i = 0; i < handlerUp.getSlots(); i++) {
@ -139,8 +138,5 @@ public class BlockEntityGratedChute extends BlockEntityImpl implements ITickable
}
}
@Override
public IItemHandlerModifiable getItemHandler() {
return this.items;
}
}

View file

@ -12,7 +12,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.HopperBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.neoforged.neoforge.common.capabilities.Capabilities;
import net.neoforged.neoforge.capabilities.Capabilities;
public class BlockEntityHopperUpgrade extends BlockEntityImpl implements ITickableBlockEntity {
@ -36,7 +36,7 @@ public class BlockEntityHopperUpgrade extends BlockEntityImpl implements ITickab
var tile = this.level.getBlockEntity(this.worldPosition.below());
if (!BlockEntityHopperUpgrade.isValidHopper(tile))
return;
var handler = tile.getCapability(Capabilities.ITEM_HANDLER, Direction.UP).orElse(null);
var handler = this.level.getCapability(Capabilities.ItemHandler.BLOCK, tile.getBlockPos(), tile.getBlockState(), tile, Direction.UP);
if (handler == null)
return;
@ -82,4 +82,5 @@ public class BlockEntityHopperUpgrade extends BlockEntityImpl implements ITickab
public boolean allowsLowerLimiter() {
return true;
}
}

View file

@ -1,8 +1,6 @@
package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.container.IAuraContainer;
import de.ellpeck.naturesaura.blocks.ModBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@ -16,19 +14,11 @@ import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.common.capabilities.Capabilities;
import net.neoforged.neoforge.common.util.LazyOptional;
import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.items.IItemHandlerModifiable;
import net.neoforged.neoforge.common.capabilities.Capability;
import javax.annotation.Nullable;
import net.neoforged.neoforge.capabilities.Capabilities;
public class BlockEntityImpl extends BlockEntity {
public int redstonePower;
private LazyOptional<IItemHandler> itemHandler;
private LazyOptional<IAuraContainer> auraContainer;
public BlockEntityImpl(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
@ -97,45 +87,8 @@ public class BlockEntityImpl extends BlockEntity {
e.connection.send(packet);
}
public IItemHandlerModifiable getItemHandler() {
return null;
}
public IAuraContainer getAuraContainer() {
return null;
}
@Nullable
@Override
public <T> LazyOptional<T> getCapability(Capability<T> capability, @Nullable Direction facing) {
if (capability == Capabilities.ITEM_HANDLER) {
if (this.itemHandler == null) {
IItemHandler handler = this.getItemHandler();
this.itemHandler = handler == null ? LazyOptional.empty() : LazyOptional.of(() -> handler);
}
return this.itemHandler.cast();
} else if (capability == NaturesAuraAPI.CAP_AURA_CONTAINER) {
if (this.auraContainer == null) {
var container = this.getAuraContainer();
this.auraContainer = container == null ? LazyOptional.empty() : LazyOptional.of(() -> container);
}
return this.auraContainer.cast();
} else {
return super.getCapability(capability, facing);
}
}
@Override
public void setRemoved() {
super.setRemoved();
if (this.itemHandler != null)
this.itemHandler.invalidate();
if (this.auraContainer != null)
this.auraContainer.invalidate();
}
public void dropInventory() {
IItemHandler handler = this.getItemHandler();
var handler = this.level.getCapability(Capabilities.ItemHandler.BLOCK, this.worldPosition, this.getBlockState(), this, null);
if (handler != null) {
for (var i = 0; i < handler.getSlots(); i++) {
var stack = handler.getStackInSlot(i);
@ -207,4 +160,5 @@ public class BlockEntityImpl extends BlockEntity {
public enum SaveType {
TILE, SYNC, BLOCK
}
}

View file

@ -5,7 +5,7 @@ import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.common.capabilities.Capabilities;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.items.IItemHandler;
import java.util.ArrayList;
@ -57,7 +57,7 @@ public class BlockEntityItemDistributor extends BlockEntityImpl implements ITick
var tile = this.level.getBlockEntity(offset);
if (tile == null)
return null;
return tile.getCapability(Capabilities.ITEM_HANDLER, direction.getOpposite()).orElse(null);
return this.level.getCapability(Capabilities.ItemHandler.BLOCK, tile.getBlockPos(), tile.getBlockState(), tile, direction.getOpposite());
}
private IItemHandler getNextSide() {
@ -103,4 +103,5 @@ public class BlockEntityItemDistributor extends BlockEntityImpl implements ITick
if (type != SaveType.BLOCK)
this.isRandomMode = compound.getBoolean("random");
}
}

View file

@ -2,9 +2,6 @@ package de.ellpeck.naturesaura.blocks.tiles;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
public class BlockEntityLowerLimiter extends BlockEntityImpl {
@ -12,9 +9,4 @@ public class BlockEntityLowerLimiter extends BlockEntityImpl {
super(ModBlockEntities.LOWER_LIMITER, pos, state);
}
@Override
@OnlyIn(Dist.CLIENT)
public AABB getRenderBoundingBox() {
return new AABB(this.worldPosition, this.worldPosition.offset(1, 2, 1));
}
}

View file

@ -12,6 +12,7 @@ import de.ellpeck.naturesaura.packet.PacketParticles;
import de.ellpeck.naturesaura.recipes.AltarRecipe;
import de.ellpeck.naturesaura.recipes.ModRecipes;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvents;
@ -19,6 +20,7 @@ import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
@ -27,7 +29,7 @@ import net.neoforged.neoforge.items.ItemStackHandler;
public class BlockEntityNatureAltar extends BlockEntityImpl implements ITickableBlockEntity {
private final BasicAuraContainer container = new BasicAuraContainer(null, 500000) {
public final BasicAuraContainer container = new BasicAuraContainer(null, 500000) {
@Override
public int getAuraColor() {
return IAuraType.forLevel(BlockEntityNatureAltar.this.level).getColor();
@ -42,12 +44,12 @@ public class BlockEntityNatureAltar extends BlockEntityImpl implements ITickable
@Override
protected boolean canInsert(ItemStack stack, int slot) {
return BlockEntityNatureAltar.this.getRecipeForInput(stack) != null || stack.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER, null).isPresent();
return BlockEntityNatureAltar.this.getRecipeForInput(stack) != null || stack.getCapability(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY, null) != null;
}
@Override
protected boolean canExtract(ItemStack stack, int slot, int amount) {
var cap = stack.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER, null).orElse(null);
var cap = stack.getCapability(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY);
if (cap != null) {
return cap.storeAura(1, true) <= 0;
} else {
@ -59,7 +61,7 @@ public class BlockEntityNatureAltar extends BlockEntityImpl implements ITickable
public int bobTimer;
public boolean isComplete;
private AltarRecipe currentRecipe;
private RecipeHolder<AltarRecipe> currentRecipe;
private int timer;
private int lastAura;
private boolean firstTick = true;
@ -118,7 +120,7 @@ public class BlockEntityNatureAltar extends BlockEntityImpl implements ITickable
}
var stack = this.items.getStackInSlot(0);
var container = stack.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER, null).orElse(null);
var container = stack.getCapability(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY);
if (!stack.isEmpty() && container != null) {
var theoreticalDrain = this.container.drainAura(1000, true);
if (theoreticalDrain > 0) {
@ -136,11 +138,11 @@ public class BlockEntityNatureAltar extends BlockEntityImpl implements ITickable
this.currentRecipe = this.getRecipeForInput(stack);
}
} else {
if (stack.isEmpty() || !this.currentRecipe.input.test(stack)) {
if (stack.isEmpty() || !this.currentRecipe.value().input.test(stack)) {
this.currentRecipe = null;
this.timer = 0;
} else {
var req = Mth.ceil(this.currentRecipe.aura / (double) this.currentRecipe.time);
var req = Mth.ceil(this.currentRecipe.value().aura / (double) this.currentRecipe.value().time);
if (this.container.getStoredAura() >= req) {
this.container.drainAura(req, false);
@ -148,8 +150,8 @@ public class BlockEntityNatureAltar extends BlockEntityImpl implements ITickable
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticles(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), PacketParticles.Type.ALTAR_CONVERSION, this.container.getAuraColor()));
this.timer++;
if (this.timer >= this.currentRecipe.time) {
this.items.setStackInSlot(0, this.currentRecipe.output.copy());
if (this.timer >= this.currentRecipe.value().time) {
this.items.setStackInSlot(0, this.currentRecipe.value().output.copy());
this.currentRecipe = null;
this.timer = 0;
@ -197,14 +199,15 @@ public class BlockEntityNatureAltar extends BlockEntityImpl implements ITickable
}
}
private AltarRecipe getRecipeForInput(ItemStack input) {
for (var recipe : this.level.getRecipeManager().getRecipesFor(ModRecipes.ALTAR_TYPE, null, this.level)) {
private RecipeHolder<AltarRecipe> getRecipeForInput(ItemStack input) {
for (var holder : this.level.getRecipeManager().getRecipesFor(ModRecipes.ALTAR_TYPE, null, this.level)) {
var recipe = holder.value();
if (recipe.input.test(input)) {
if (recipe.catalyst == Ingredient.EMPTY)
return recipe;
return holder;
for (var stack : this.catalysts) {
if (recipe.catalyst.test(stack))
return recipe;
return holder;
}
}
}
@ -221,12 +224,13 @@ public class BlockEntityNatureAltar extends BlockEntityImpl implements ITickable
}
if (type == SaveType.TILE) {
if (this.currentRecipe != null) {
compound.putString("recipe", this.currentRecipe.name.toString());
compound.putString("recipe", this.currentRecipe.id().toString());
compound.putInt("timer", this.timer);
}
}
}
@SuppressWarnings("unchecked")
@Override
public void readNBT(CompoundTag compound, SaveType type) {
super.readNBT(compound, type);
@ -238,19 +242,10 @@ public class BlockEntityNatureAltar extends BlockEntityImpl implements ITickable
if (type == SaveType.TILE) {
if (compound.contains("recipe")) {
if (this.hasLevel())
this.currentRecipe = (AltarRecipe) this.level.getRecipeManager().byKey(new ResourceLocation(compound.getString("recipe"))).orElse(null);
this.currentRecipe = (RecipeHolder<AltarRecipe>) this.level.getRecipeManager().byKey(new ResourceLocation(compound.getString("recipe"))).orElse(null);
this.timer = compound.getInt("timer");
}
}
}
@Override
public IAuraContainer getAuraContainer() {
return this.container;
}
@Override
public IItemHandlerModifiable getItemHandler() {
return this.items;
}
}

View file

@ -17,7 +17,6 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.items.IItemHandlerModifiable;
import net.neoforged.neoforge.items.ItemStackHandler;
import java.util.ArrayDeque;
@ -39,8 +38,8 @@ public class BlockEntityOfferingTable extends BlockEntityImpl implements ITickab
private OfferingRecipe getRecipe(ItemStack input) {
for (var recipe : this.level.getRecipeManager().getRecipesFor(ModRecipes.OFFERING_TYPE, null, this.level))
if (recipe.input.test(input))
return recipe;
if (recipe.value().input.test(input))
return recipe.value();
return null;
}
@ -114,7 +113,7 @@ public class BlockEntityOfferingTable extends BlockEntityImpl implements ITickab
if (type != SaveType.SYNC) {
var list = new ListTag();
for (var stack : this.itemsToSpawn)
list.add(stack.serializeNBT());
list.add(stack.save(new CompoundTag()));
compound.put("items_to_spawn", list);
}
}
@ -135,9 +134,4 @@ public class BlockEntityOfferingTable extends BlockEntityImpl implements ITickab
}
}
@Override
public IItemHandlerModifiable getItemHandler() {
return this.items;
}
}

View file

@ -16,9 +16,9 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.common.CommonHooks;
import net.neoforged.neoforge.common.util.FakePlayerFactory;
import net.neoforged.neoforge.common.capabilities.Capabilities;
import java.util.ArrayList;
import java.util.List;
@ -37,7 +37,7 @@ public class BlockEntityPlacer extends BlockEntityImpl implements ITickableBlock
var tileUp = this.level.getBlockEntity(this.worldPosition.above());
if (tileUp == null)
return;
var handler = tileUp.getCapability(Capabilities.ITEM_HANDLER, Direction.DOWN).orElse(null);
var handler = this.level.getCapability(Capabilities.ItemHandler.BLOCK, tileUp.getBlockPos(), tileUp.getBlockState(), tileUp, Direction.DOWN);
if (handler == null)
return;
var frames = Helper.getAttachedItemFrames(this.level, this.worldPosition);
@ -118,4 +118,5 @@ public class BlockEntityPlacer extends BlockEntityImpl implements ITickableBlock
CommonHooks.onPlaceItemIntoWorld(new UseOnContext(fake, InteractionHand.MAIN_HAND, ray));
return fake.getMainHandItem().copy();
}
}

View file

@ -7,7 +7,8 @@ import net.minecraft.core.Direction;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.neoforged.neoforge.common.capabilities.Capabilities;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.capabilities.Capabilities;
public class BlockEntityPowderPlacer extends BlockEntityImpl {
@ -18,14 +19,14 @@ public class BlockEntityPowderPlacer extends BlockEntityImpl {
@Override
public void onRedstonePowerChange(int newPower) {
if (this.redstonePower <= 0 && newPower > 0) {
var powders = this.level.getEntitiesOfClass(EntityEffectInhibitor.class, new AABB(this.worldPosition, this.worldPosition.offset(1, 2, 1)), Entity::isAlive);
var powders = this.level.getEntitiesOfClass(EntityEffectInhibitor.class, new AABB(Vec3.atCenterOf(this.worldPosition), Vec3.atCenterOf(this.worldPosition.offset(1, 2, 1))), Entity::isAlive);
for (var facing : Direction.values()) {
if (!facing.getAxis().isHorizontal())
continue;
var tile = this.level.getBlockEntity(this.worldPosition.relative(facing));
if (tile == null)
continue;
var handler = tile.getCapability(Capabilities.ITEM_HANDLER, facing.getOpposite()).orElse(null);
var handler = this.level.getCapability(Capabilities.ItemHandler.BLOCK, tile.getBlockPos(), tile.getBlockState(), tile, facing.getOpposite());
if (handler == null)
continue;
@ -56,4 +57,5 @@ public class BlockEntityPowderPlacer extends BlockEntityImpl {
}
super.onRedstonePowerChange(newPower);
}
}

View file

@ -10,18 +10,12 @@ import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.common.capabilities.Capability;
import net.neoforged.neoforge.common.capabilities.Capabilities;
import net.neoforged.neoforge.common.util.LazyOptional;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.energy.EnergyStorage;
import net.neoforged.neoforge.energy.IEnergyStorage;
import javax.annotation.Nullable;
public class BlockEntityRFConverter extends BlockEntityImpl implements ITickableBlockEntity {
public final RFStorage storage = new RFStorage();
private final LazyOptional<IEnergyStorage> storageOptional = LazyOptional.of(() -> this.storage);
private int lastEnergy;
public BlockEntityRFConverter(BlockPos pos, BlockState state) {
@ -52,7 +46,7 @@ public class BlockEntityRFConverter extends BlockEntityImpl implements ITickable
var tile = this.level.getBlockEntity(this.worldPosition.relative(facing));
if (tile == null)
continue;
var storage = tile.getCapability(Capabilities.ENERGY, facing.getOpposite()).orElse(null);
var storage = this.level.getCapability(Capabilities.EnergyStorage.BLOCK, tile.getBlockPos(), tile.getBlockState(), tile, facing.getOpposite());
if (storage == null)
continue;
var canStore = storage.receiveEnergy(Integer.MAX_VALUE, true);
@ -88,19 +82,9 @@ public class BlockEntityRFConverter extends BlockEntityImpl implements ITickable
}
}
@Nullable
@Override
public <T> LazyOptional<T> getCapability(Capability<T> capability, @Nullable Direction facing) {
if (capability == Capabilities.ENERGY)
return this.storageOptional.cast();
else
return super.getCapability(capability, facing);
}
@Override
public void setRemoved() {
super.setRemoved();
this.storageOptional.invalidate();
}
public static class RFStorage extends EnergyStorage {
@ -112,5 +96,7 @@ public class BlockEntityRFConverter extends BlockEntityImpl implements ITickable
public void setEnergy(int energy) {
this.energy = energy;
}
}
}

View file

@ -14,18 +14,15 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.AABB;
import net.neoforged.neoforge.common.FarmlandWaterManager;
import net.neoforged.neoforge.common.capabilities.Capability;
import net.neoforged.neoforge.common.capabilities.Capabilities;
import net.neoforged.neoforge.common.ticket.AABBTicket;
import net.neoforged.neoforge.event.EventHooks;
import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.IFluidTank;
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
import net.neoforged.neoforge.common.util.LazyOptional;
public class BlockEntitySpring extends BlockEntityImpl implements ITickableBlockEntity {
private final LazyOptional<IFluidHandler> tank = LazyOptional.of(InfiniteTank::new);
public final IFluidHandler tank = new InfiniteTank();
private AABBTicket waterTicket;
public BlockEntitySpring(BlockPos pos, BlockState state) {
@ -49,7 +46,6 @@ public class BlockEntitySpring extends BlockEntityImpl implements ITickableBlock
this.waterTicket.invalidate();
this.waterTicket = null;
}
this.tank.invalidate();
}
@Override
@ -115,13 +111,6 @@ public class BlockEntitySpring extends BlockEntityImpl implements ITickableBlock
}
}
@Override
public <T> LazyOptional<T> getCapability(Capability<T> capability, Direction facing) {
if (capability == Capabilities.FLUID_HANDLER)
return this.tank.cast();
return LazyOptional.empty();
}
@Override
public boolean allowsLowerLimiter() {
return true;
@ -204,5 +193,7 @@ public class BlockEntitySpring extends BlockEntityImpl implements ITickableBlock
public boolean isFluidValid(int tank, FluidStack stack) {
return this.isFluidValid(stack);
}
}
}

View file

@ -15,14 +15,13 @@ import net.minecraft.tags.BlockTags;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LeavesBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.items.IItemHandlerModifiable;
import net.neoforged.neoforge.items.ItemStackHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BlockEntityWoodStand extends BlockEntityImpl implements ITickableBlockEntity {
@ -34,7 +33,7 @@ public class BlockEntityWoodStand extends BlockEntityImpl implements ITickableBl
}
};
private TreeRitualRecipe recipe;
private RecipeHolder<TreeRitualRecipe> recipe;
private BlockPos ritualPos;
private int timer;
@ -42,7 +41,7 @@ public class BlockEntityWoodStand extends BlockEntityImpl implements ITickableBl
super(ModBlockEntities.WOOD_STAND, pos, state);
}
public void setRitual(BlockPos pos, TreeRitualRecipe recipe) {
public void setRitual(BlockPos pos, RecipeHolder<TreeRitualRecipe> recipe) {
this.ritualPos = pos;
this.recipe = recipe;
}
@ -53,9 +52,9 @@ public class BlockEntityWoodStand extends BlockEntityImpl implements ITickableBl
if (this.ritualPos != null && this.recipe != null) {
if (this.level.getGameTime() % 5 == 0) {
if (this.isRitualOkay()) {
var wasOverHalf = this.timer >= this.recipe.time / 2;
var wasOverHalf = this.timer >= this.recipe.value().time / 2;
this.timer += 5;
var isOverHalf = this.timer >= this.recipe.time / 2;
var isOverHalf = this.timer >= this.recipe.value().time / 2;
if (!isOverHalf)
Multiblocks.TREE_RITUAL.forEach(this.ritualPos, 'W', (pos, matcher) -> {
@ -75,7 +74,7 @@ public class BlockEntityWoodStand extends BlockEntityImpl implements ITickableBl
PacketHandler.sendToAllAround(this.level, this.ritualPos, 32,
new PacketParticles(this.ritualPos.getX(), this.ritualPos.getY(), this.ritualPos.getZ(), PacketParticles.Type.TR_GOLD_POWDER));
if (this.timer >= this.recipe.time) {
if (this.timer >= this.recipe.value().time) {
Multiblocks.TREE_RITUAL.forEach(this.ritualPos, 'G', (pos, matcher) -> {
this.level.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState());
return true;
@ -84,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.result.copy());
this.recipe.value().result.copy());
this.level.addFreshEntity(item);
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32,
@ -130,8 +129,8 @@ public class BlockEntityWoodStand extends BlockEntityImpl implements ITickableBl
if (!state.is(BlockTags.LOGS))
return false;
}
if (this.timer < this.recipe.time / 2) {
List<Ingredient> required = new ArrayList<>(Arrays.asList(this.recipe.ingredients));
if (this.timer < this.recipe.value().time / 2) {
List<Ingredient> required = new ArrayList<>(this.recipe.value().ingredients);
var fine = Multiblocks.TREE_RITUAL.forEach(this.ritualPos, 'W', (pos, matcher) -> {
var tile = this.level.getBlockEntity(pos);
if (tile instanceof BlockEntityWoodStand) {
@ -164,11 +163,12 @@ public class BlockEntityWoodStand extends BlockEntityImpl implements ITickableBl
if (this.ritualPos != null && this.recipe != null) {
compound.putLong("ritual_pos", this.ritualPos.asLong());
compound.putInt("timer", this.timer);
compound.putString("recipe", this.recipe.name.toString());
compound.putString("recipe", this.recipe.toString());
}
}
}
@SuppressWarnings("unchecked")
@Override
public void readNBT(CompoundTag compound, SaveType type) {
super.readNBT(compound, type);
@ -180,14 +180,9 @@ public class BlockEntityWoodStand extends BlockEntityImpl implements ITickableBl
this.ritualPos = BlockPos.of(compound.getLong("ritual_pos"));
this.timer = compound.getInt("timer");
if (this.hasLevel())
this.recipe = (TreeRitualRecipe) this.level.getRecipeManager().byKey(new ResourceLocation(compound.getString("recipe"))).orElse(null);
this.recipe = (RecipeHolder<TreeRitualRecipe>) this.level.getRecipeManager().byKey(new ResourceLocation(compound.getString("recipe"))).orElse(null);
}
}
}
@Override
public IItemHandlerModifiable getItemHandler() {
return this.items;
}
}

View file

@ -33,17 +33,23 @@ import java.util.function.BiConsumer;
public class AuraChunk implements IAuraChunk {
private final LevelChunk chunk;
private final IAuraType type;
private final Map<BlockPos, DrainSpot> drainSpots = new ConcurrentHashMap<>();
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 LevelChunk chunk;
private IAuraType type;
private boolean needsSync;
public AuraChunk(LevelChunk chunk, IAuraType type) {
@Override
public void ensureInitialized(LevelChunk chunk) {
// are we already initialized?
if (this.chunk != null)
return;
this.chunk = chunk;
this.type = type;
this.type = IAuraType.forLevel(chunk.getLevel());
for (var supplier : NaturesAuraAPI.DRAIN_SPOT_EFFECTS.values()) {
var effect = supplier.get();
@ -269,7 +275,7 @@ public class AuraChunk implements IAuraChunk {
private void addOrRemoveAsActive() {
var chunkPos = this.chunk.getPos().toLong();
var data = (LevelData) ILevelData.getLevelData(this.chunk.getLevel());
if (this.drainSpots.size() > 0) {
if (!this.drainSpots.isEmpty()) {
data.auraChunksWithSpots.put(chunkPos, this);
} else {
data.auraChunksWithSpots.remove(chunkPos);
@ -300,5 +306,7 @@ public class AuraChunk implements IAuraChunk {
ret.putLong("original_spread_pos", this.originalSpreadPos.asLong());
return ret;
}
}
}

View file

@ -1,48 +0,0 @@
package de.ellpeck.naturesaura.chunk;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.chunk.LevelChunk;
import net.neoforged.neoforge.common.capabilities.Capability;
import net.neoforged.neoforge.common.capabilities.ICapabilityProvider;
import net.neoforged.neoforge.common.util.INBTSerializable;
import net.neoforged.neoforge.common.util.LazyOptional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class AuraChunkProvider implements ICapabilityProvider, INBTSerializable<CompoundTag> {
private final LevelChunk chunk;
private final LazyOptional<IAuraChunk> lazyChunk = LazyOptional.of(this::getAuraChunk);
private IAuraChunk auraChunk;
public AuraChunkProvider(LevelChunk chunk) {
this.chunk = chunk;
}
private IAuraChunk getAuraChunk() {
if (this.auraChunk == null)
this.auraChunk = new AuraChunk(this.chunk, IAuraType.forLevel(this.chunk.getLevel()));
return this.auraChunk;
}
@Nullable
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable Direction facing) {
return capability == NaturesAuraAPI.CAP_AURA_CHUNK ? this.lazyChunk.cast() : LazyOptional.empty();
}
@Override
public CompoundTag serializeNBT() {
return this.getAuraChunk().serializeNBT();
}
@Override
public void deserializeNBT(CompoundTag nbt) {
this.getAuraChunk().deserializeNBT(nbt);
}
}

View file

@ -10,6 +10,8 @@ import de.ellpeck.naturesaura.api.misc.WeightedOre;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.TagKey;
@ -29,7 +31,6 @@ import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.common.util.FakePlayerFactory;
import net.neoforged.neoforge.registries.ForgeRegistries;
import java.util.HashSet;
import java.util.List;
@ -114,11 +115,14 @@ public class OreSpawnEffect implements IDrainSpotEffect {
var ore = WeightedRandom.getRandomItem(level.random, ores, totalWeight).orElse(null);
if (ore == null)
continue;
var tag = TagKey.create(ForgeRegistries.Keys.BLOCKS, ore.tag);
var tag = TagKey.create(Registries.BLOCK, ore.tag);
if (tag == null)
continue;
for (var toPlace : ForgeRegistries.BLOCKS.tags().getTag(tag)) {
if (toPlace == null || toPlace == Blocks.AIR)
for (var toPlaceHolder : BuiltInRegistries.BLOCK.getTag(tag).orElseThrow()) {
if (toPlaceHolder == null)
continue;
var toPlace = toPlaceHolder.value();
if (toPlace == Blocks.AIR)
continue;
var player = FakePlayerFactory.getMinecraft((ServerLevel) level);
@ -152,4 +156,5 @@ public class OreSpawnEffect implements IDrainSpotEffect {
public ResourceLocation getName() {
return OreSpawnEffect.NAME;
}
}

View file

@ -79,7 +79,7 @@ public class PlantBoostEffect implements IDrainSpotEffect {
var state = level.getBlockState(plantPos);
var block = state.getBlock();
if (block instanceof BonemealableBlock growable && !PlantBoostEffect.EXCEPTIONS.contains(block) && !(block instanceof DoublePlantBlock) && !(block instanceof TallGrassBlock)) {
if (growable.isValidBonemealTarget(level, plantPos, state, false)) {
if (growable.isValidBonemealTarget(level, plantPos, state)) {
try {
growable.performBonemeal((ServerLevel) level, level.random, plantPos, state);
} catch (Exception e) {

View file

@ -25,7 +25,7 @@ public class ReplenishingEffect implements IDrainSpotEffect {
if (spot < 0) {
List<ISpotDrainable> tiles = new ArrayList<>();
Helper.getBlockEntitiesInArea(level, pos, 25, tile -> {
var container = tile.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER, null).orElse(null);
var container = level.getCapability(NaturesAuraAPI.AURA_CONTAINER_BLOCK_CAPABILITY, tile.getBlockPos(), tile.getBlockState(), tile, null);
if (container instanceof ISpotDrainable)
tiles.add((ISpotDrainable) container);
return false;
@ -58,4 +58,5 @@ public class ReplenishingEffect implements IDrainSpotEffect {
public ResourceLocation getName() {
return ReplenishingEffect.NAME;
}
}

View file

@ -23,6 +23,7 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.SpawnEggItem;
import net.neoforged.neoforge.common.DeferredSpawnEggItem;
import java.util.Arrays;
@ -103,9 +104,9 @@ public class AnimalSpawnerCategory implements IRecipeCategory<AnimalSpawnerRecip
@Override
public void setRecipe(IRecipeLayoutBuilder builder, AnimalSpawnerRecipe recipe, IFocusGroup focuses) {
for (var i = 0; i < recipe.ingredients.length; i++)
builder.addSlot(RecipeIngredientRole.INPUT, i * 18 + 1, 69).addItemStacks(Arrays.asList(recipe.ingredients[i].getItems()));
builder.addInvisibleIngredients(RecipeIngredientRole.OUTPUT).addItemStack(new ItemStack(DeferredSpawnEggItem.fromEntityType(recipe.entity)));
for (var i = 0; i < recipe.ingredients.size(); i++)
builder.addSlot(RecipeIngredientRole.INPUT, i * 18 + 1, 69).addItemStacks(Arrays.asList(recipe.ingredients.get(i).getItems()));
builder.addInvisibleIngredients(RecipeIngredientRole.OUTPUT).addItemStack(new ItemStack(SpawnEggItem.byId(recipe.entity)));
}
@Override

View file

@ -19,6 +19,7 @@ import mezz.jei.api.registration.ISubtypeRegistration;
import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeHolder;
@JeiPlugin
public class JEINaturesAuraPlugin implements IModPlugin {
@ -50,7 +51,7 @@ public class JEINaturesAuraPlugin implements IModPlugin {
registration.registerSubtypeInterpreter(VanillaTypes.ITEM_STACK, ModItems.AURA_BOTTLE, (stack, context) -> ItemAuraBottle.getType(stack).getName().toString());
var auraInterpreter = (IIngredientSubtypeInterpreter<ItemStack>) (stack, context) -> {
var container = stack.getCapability(NaturesAuraAPI.CAP_AURA_CONTAINER).orElse(null);
var container = stack.getCapability(NaturesAuraAPI.AURA_CONTAINER_ITEM_CAPABILITY);
if (container != null)
return String.valueOf(container.getStoredAura());
return IIngredientSubtypeInterpreter.NONE;
@ -71,9 +72,10 @@ public class JEINaturesAuraPlugin implements IModPlugin {
@Override
public void registerRecipes(IRecipeRegistration registration) {
var manager = Minecraft.getInstance().level.getRecipeManager();
registration.addRecipes(JEINaturesAuraPlugin.TREE_RITUAL, manager.getAllRecipesFor(ModRecipes.TREE_RITUAL_TYPE));
registration.addRecipes(JEINaturesAuraPlugin.ALTAR, manager.getAllRecipesFor(ModRecipes.ALTAR_TYPE));
registration.addRecipes(JEINaturesAuraPlugin.OFFERING, manager.getAllRecipesFor(ModRecipes.OFFERING_TYPE));
registration.addRecipes(JEINaturesAuraPlugin.SPAWNER, manager.getAllRecipesFor(ModRecipes.ANIMAL_SPAWNER_TYPE));
registration.addRecipes(JEINaturesAuraPlugin.TREE_RITUAL, manager.getAllRecipesFor(ModRecipes.TREE_RITUAL_TYPE).stream().map(RecipeHolder::value).toList());
registration.addRecipes(JEINaturesAuraPlugin.ALTAR, manager.getAllRecipesFor(ModRecipes.ALTAR_TYPE).stream().map(RecipeHolder::value).toList());
registration.addRecipes(JEINaturesAuraPlugin.OFFERING, manager.getAllRecipesFor(ModRecipes.OFFERING_TYPE).stream().map(RecipeHolder::value).toList());
registration.addRecipes(JEINaturesAuraPlugin.SPAWNER, manager.getAllRecipesFor(ModRecipes.ANIMAL_SPAWNER_TYPE).stream().map(RecipeHolder::value).toList());
}
}

View file

@ -48,8 +48,8 @@ public class TreeRitualCategory implements IRecipeCategory<TreeRitualRecipe> {
builder.addSlot(RecipeIngredientRole.OUTPUT, 125, 35).addItemStack(recipe.result);
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.length; i++)
builder.addSlot(RecipeIngredientRole.INPUT, positions[i][0], positions[i][1]).addItemStacks(Arrays.asList(recipe.ingredients[i].getItems()));
for (var i = 0; i < recipe.ingredients.size(); i++)
builder.addSlot(RecipeIngredientRole.INPUT, positions[i][0], positions[i][1]).addItemStacks(Arrays.asList(recipe.ingredients.get(i).getItems()));
}
}

View file

@ -54,7 +54,7 @@ public class PatchouliCompat implements ICompat {
var manager = Minecraft.getInstance().level.getRecipeManager();
var res = new ResourceLocation(name);
var pre = new ResourceLocation(res.getNamespace(), type + "/" + res.getPath());
return (T) manager.byKey(pre).orElse(null);
return (T) manager.byKey(pre).orElse(null).value();
}
public static IVariable ingredientVariable(Ingredient ingredient) {

View file

@ -1,10 +1,10 @@
package de.ellpeck.naturesaura.compat.patchouli;
import de.ellpeck.naturesaura.recipes.AnimalSpawnerRecipe;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.SpawnEggItem;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.common.DeferredSpawnEggItem;
import net.neoforged.neoforge.registries.ForgeRegistries;
import vazkii.patchouli.api.IComponentProcessor;
import vazkii.patchouli.api.IVariable;
import vazkii.patchouli.api.IVariableProvider;
@ -24,12 +24,12 @@ public class ProcessorAnimalSpawner implements IComponentProcessor {
return null;
if (key.startsWith("input")) {
var id = Integer.parseInt(key.substring(5)) - 1;
return this.recipe.ingredients.length > id ? PatchouliCompat.ingredientVariable(this.recipe.ingredients[id]) : null;
return this.recipe.ingredients.size() > id ? PatchouliCompat.ingredientVariable(this.recipe.ingredients.get(id)) : null;
} else {
return switch (key) {
case "name" -> IVariable.wrap(this.recipe.entity.getDescription().getString());
case "entity" -> IVariable.wrap(ForgeRegistries.ENTITY_TYPES.getKey(this.recipe.entity).toString());
case "egg" -> IVariable.from(new ItemStack(DeferredSpawnEggItem.fromEntityType(this.recipe.entity)));
case "entity" -> IVariable.wrap(BuiltInRegistries.ENTITY_TYPE.getKey(this.recipe.entity).toString());
case "egg" -> IVariable.from(new ItemStack(SpawnEggItem.byId(this.recipe.entity)));
default -> null;
};
}
@ -39,4 +39,5 @@ public class ProcessorAnimalSpawner implements IComponentProcessor {
public boolean allowRender(String group) {
return !"seekrit".equals(group);
}
}

View file

@ -21,7 +21,7 @@ public class ProcessorTreeRitual implements IComponentProcessor {
return null;
if (key.startsWith("input")) {
var id = Integer.parseInt(key.substring(5)) - 1;
return this.recipe.ingredients.length > id ? PatchouliCompat.ingredientVariable(this.recipe.ingredients[id]) : null;
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);

View file

@ -2,58 +2,58 @@ package de.ellpeck.naturesaura.data;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.gen.ModFeatures;
import net.minecraft.core.HolderGetter;
import net.minecraft.core.HolderSet;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.worldgen.BootstapContext;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BiomeTags;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
import net.neoforged.neoforge.common.Tags;
import net.neoforged.neoforge.common.world.BiomeModifier;
import net.neoforged.neoforge.registries.ForgeRegistries;
import net.neoforged.neoforge.common.world.BiomeModifiers.AddFeaturesBiomeModifier;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
public class BiomeModifiers {
public static ResourceKey<BiomeModifier> AURA_BLOOM = createKey("aura_bloom");
public static ResourceKey<BiomeModifier> AURA_CACTUS = createKey("aura_cactus");
public static ResourceKey<BiomeModifier> WARPED_AURA_MUSHROOM = createKey("warped_aura_mushroom");
public static ResourceKey<BiomeModifier> CRIMSON_AURA_MUSHROOM = createKey("crimson_aura_mushroom");
public static ResourceKey<BiomeModifier> AURA_MUSHROOM = createKey("aura_mushroom");
private static ResourceKey<BiomeModifier> createKey(String id) {
return ResourceKey.create(ForgeRegistries.Keys.BIOME_MODIFIERS, new ResourceLocation(NaturesAura.MOD_ID, id));
}
public static final ResourceKey<BiomeModifier> AURA_BLOOM = BiomeModifiers.createKey("aura_bloom");
public static final ResourceKey<BiomeModifier> AURA_CACTUS = BiomeModifiers.createKey("aura_cactus");
public static final ResourceKey<BiomeModifier> WARPED_AURA_MUSHROOM = BiomeModifiers.createKey("warped_aura_mushroom");
public static final ResourceKey<BiomeModifier> CRIMSON_AURA_MUSHROOM = BiomeModifiers.createKey("crimson_aura_mushroom");
public static final ResourceKey<BiomeModifier> AURA_MUSHROOM = BiomeModifiers.createKey("aura_mushroom");
public static void bootstrap(BootstapContext<BiomeModifier> context) {
HolderGetter<Biome> biomeGetter = context.lookup(Registries.BIOME);
HolderGetter<PlacedFeature> placedGetter = context.lookup(Registries.PLACED_FEATURE);
private static ResourceKey<BiomeModifier> createKey(String id) {
return ResourceKey.create(NeoForgeRegistries.Keys.BIOME_MODIFIERS, new ResourceLocation(NaturesAura.MOD_ID, id));
}
context.register(AURA_BLOOM, new net.neoforged.neoforge.common.world.BiomeModifiers.AddFeaturesBiomeModifier(
biomeGetter.getOrThrow(BiomeTags.IS_OVERWORLD),
HolderSet.direct(placedGetter.getOrThrow(ModFeatures.Placed.AURA_BLOOM)),
GenerationStep.Decoration.VEGETAL_DECORATION));
public static void bootstrap(BootstapContext<BiomeModifier> context) {
var biomeGetter = context.lookup(Registries.BIOME);
var placedGetter = context.lookup(Registries.PLACED_FEATURE);
context.register(AURA_CACTUS, new net.neoforged.neoforge.common.world.BiomeModifiers.AddFeaturesBiomeModifier(
biomeGetter.getOrThrow(Tags.Biomes.IS_SANDY),
HolderSet.direct(placedGetter.getOrThrow(ModFeatures.Placed.AURA_CACTUS)),
GenerationStep.Decoration.VEGETAL_DECORATION));
context.register(BiomeModifiers.AURA_BLOOM, new AddFeaturesBiomeModifier(
biomeGetter.getOrThrow(BiomeTags.IS_OVERWORLD),
HolderSet.direct(placedGetter.getOrThrow(ModFeatures.Placed.AURA_BLOOM)),
GenerationStep.Decoration.VEGETAL_DECORATION));
context.register(AURA_MUSHROOM, new net.neoforged.neoforge.common.world.BiomeModifiers.AddFeaturesBiomeModifier(
biomeGetter.getOrThrow(Tags.Biomes.IS_MUSHROOM),
HolderSet.direct(placedGetter.getOrThrow(ModFeatures.Placed.AURA_MUSHROOM)),
GenerationStep.Decoration.VEGETAL_DECORATION));
context.register(BiomeModifiers.AURA_CACTUS, new AddFeaturesBiomeModifier(
biomeGetter.getOrThrow(Tags.Biomes.IS_SANDY),
HolderSet.direct(placedGetter.getOrThrow(ModFeatures.Placed.AURA_CACTUS)),
GenerationStep.Decoration.VEGETAL_DECORATION));
context.register(CRIMSON_AURA_MUSHROOM, new net.neoforged.neoforge.common.world.BiomeModifiers.AddFeaturesBiomeModifier(
biomeGetter.getOrThrow(BiomeTags.IS_NETHER),
HolderSet.direct(placedGetter.getOrThrow(ModFeatures.Placed.CRIMSON_AURA_MUSHROOM)),
GenerationStep.Decoration.VEGETAL_DECORATION));
context.register(BiomeModifiers.AURA_MUSHROOM, new AddFeaturesBiomeModifier(
biomeGetter.getOrThrow(Tags.Biomes.IS_MUSHROOM),
HolderSet.direct(placedGetter.getOrThrow(ModFeatures.Placed.AURA_MUSHROOM)),
GenerationStep.Decoration.VEGETAL_DECORATION));
context.register(BiomeModifiers.CRIMSON_AURA_MUSHROOM, new AddFeaturesBiomeModifier(
biomeGetter.getOrThrow(BiomeTags.IS_NETHER),
HolderSet.direct(placedGetter.getOrThrow(ModFeatures.Placed.CRIMSON_AURA_MUSHROOM)),
GenerationStep.Decoration.VEGETAL_DECORATION));
context.register(BiomeModifiers.WARPED_AURA_MUSHROOM, new AddFeaturesBiomeModifier(
biomeGetter.getOrThrow(BiomeTags.IS_NETHER),
HolderSet.direct(placedGetter.getOrThrow(ModFeatures.Placed.WARPED_AURA_MUSHROOM)),
GenerationStep.Decoration.VEGETAL_DECORATION));
}
context.register(WARPED_AURA_MUSHROOM, new net.neoforged.neoforge.common.world.BiomeModifiers.AddFeaturesBiomeModifier(
biomeGetter.getOrThrow(BiomeTags.IS_NETHER),
HolderSet.direct(placedGetter.getOrThrow(ModFeatures.Placed.WARPED_AURA_MUSHROOM)),
GenerationStep.Decoration.VEGETAL_DECORATION));
}
}

View file

@ -14,7 +14,7 @@ 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.registries.ForgeRegistries;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
import java.util.List;
import java.util.Set;
@ -43,11 +43,12 @@ public final class ModData {
final RegistrySetBuilder registryBuilder = new RegistrySetBuilder();
registryBuilder.add(Registries.CONFIGURED_FEATURE, ModFeatures.Configured::bootstrap);
registryBuilder.add(Registries.PLACED_FEATURE, ModFeatures.Placed::bootstrap);
registryBuilder.add(ForgeRegistries.Keys.BIOME_MODIFIERS, BiomeModifiers::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 -> {
});
RegistryAccess.Frozen regAccess = RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY);
var regAccess = RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY);
return registryBuilder.buildPatch(regAccess, VanillaRegistries.createLookup());
}
}

View file

@ -20,16 +20,11 @@ public class AuraMendingEnchantment extends ModEnchantment {
@Override
public boolean canEnchant(ItemStack stack) {
return super.canEnchant(stack) && !stack.getCapability(NaturesAuraAPI.CAP_AURA_RECHARGE).isPresent();
return super.canEnchant(stack) && stack.getCapability(NaturesAuraAPI.AURA_RECHARGE_CAPABILITY) == null;
}
@Override
public boolean canApplyAtEnchantingTable(ItemStack stack) {
return super.canApplyAtEnchantingTable(stack) && !stack.getCapability(NaturesAuraAPI.CAP_AURA_RECHARGE).isPresent();
}
@Override
public int getMaxLevel() {
return 1;
return super.canApplyAtEnchantingTable(stack) && stack.getCapability(NaturesAuraAPI.AURA_RECHARGE_CAPABILITY) == null;
}
}

View file

@ -8,17 +8,16 @@ import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.misc.ILevelData;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.chunk.AuraChunkProvider;
import de.ellpeck.naturesaura.commands.CommandAura;
import de.ellpeck.naturesaura.misc.LevelData;
import de.ellpeck.naturesaura.packet.PacketHandler;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.LevelChunk;
import net.neoforged.neoforge.event.TickEvent;
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
@ -26,8 +25,6 @@ import net.neoforged.neoforge.event.level.ChunkEvent;
import net.neoforged.neoforge.event.level.ChunkWatchEvent;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.util.ObfuscationReflectionHelper;
import net.neoforged.neoforge.registries.ForgeRegistries;
import net.neoforged.neoforge.event.AttachCapabilitiesEvent;
import net.neoforged.neoforge.event.RegisterCommandsEvent;
import java.lang.reflect.InvocationTargetException;
@ -39,22 +36,11 @@ public class CommonEvents {
private static final Method GET_LOADED_CHUNKS_METHOD = ObfuscationReflectionHelper.findMethod(ChunkMap.class, "m_140416_");
private static final ListMultimap<UUID, ChunkPos> PENDING_AURA_CHUNKS = ArrayListMultimap.create();
@SubscribeEvent
public void onChunkCapsAttach(AttachCapabilitiesEvent<LevelChunk> event) {
var chunk = event.getObject();
event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "aura"), new AuraChunkProvider(chunk));
}
@SubscribeEvent
public void onLevelCapsAttach(AttachCapabilitiesEvent<Level> event) {
event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "data"), new LevelData());
}
@SubscribeEvent
public void onChunkUnload(ChunkEvent.Unload event) {
var iChunk = event.getChunk();
if (iChunk instanceof LevelChunk chunk) {
var auraChunk = chunk.getCapability(NaturesAuraAPI.CAP_AURA_CHUNK).orElse(null);
var auraChunk = chunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT).get(chunk);
if (auraChunk instanceof AuraChunk) {
var data = (LevelData) ILevelData.getLevelData(chunk.getLevel());
data.auraChunksWithSpots.remove(chunk.getPos().toLong());
@ -68,7 +54,7 @@ public class CommonEvents {
if (player.level().isClientSide)
return;
var held = event.getItemStack();
if (!held.isEmpty() && ForgeRegistries.ITEMS.getKey(held.getItem()).getPath().contains("chisel")) {
if (!held.isEmpty() && BuiltInRegistries.ITEM.getKey(held.getItem()).getPath().contains("chisel")) {
var state = player.level().getBlockState(event.getPos());
if (NaturesAuraAPI.BOTANIST_PICKAXE_CONVERSIONS.containsKey(state)) {
var data = (LevelData) ILevelData.getLevelData(player.level());
@ -90,7 +76,7 @@ public class CommonEvents {
var chunk = holder.getTickingChunk();
if (chunk == null)
continue;
var auraChunk = (AuraChunk) chunk.getCapability(NaturesAuraAPI.CAP_AURA_CHUNK, null).orElse(null);
var auraChunk = (AuraChunk) chunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT).get(chunk);
if (auraChunk != null)
auraChunk.update();
}
@ -130,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.getCapability(NaturesAuraAPI.CAP_AURA_CHUNK, null).orElse(null);
var auraChunk = (AuraChunk) levelChunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT).get(levelChunk);
if (auraChunk == null)
return false;
PacketHandler.sendTo(player, auraChunk.makePacket());
@ -141,4 +127,5 @@ public class CommonEvents {
public void onCommands(RegisterCommandsEvent event) {
CommandAura.register(event.getDispatcher());
}
}

View file

@ -107,7 +107,7 @@ public class LevelGenAncientTree extends Feature<NoneFeatureConfiguration> {
var goal = pos.offset(x, y, z);
if (pos.distSqr(goal) <= radius * radius + rand.nextInt(3) - 1) {
if (!level.isStateAtPosition(goal, s -> s.is(BlockTags.LEAVES))) {
if (level.isStateAtPosition(goal, st -> !st.is(BlockTags.LOGS) && st.getBlock() != Blocks.DIRT && st.getBlock() != Blocks.GRASS))
if (level.isStateAtPosition(goal, st -> !st.is(BlockTags.LOGS) && st.getBlock() != Blocks.DIRT && st.getBlock() != Blocks.GRASS_BLOCK))
this.setBlock(level, goal, state);
}
}

View file

@ -20,7 +20,6 @@ public class GuiEnderCrate extends AbstractContainerScreen<ContainerEnderCrate>
@Override
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
this.renderBackground(graphics);
super.render(graphics, mouseX, mouseY, partialTicks);
this.renderTooltip(graphics, mouseX, mouseY);
}
@ -38,4 +37,5 @@ public class GuiEnderCrate extends AbstractContainerScreen<ContainerEnderCrate>
graphics.blit(GuiEnderCrate.CHEST_GUI_TEXTURE, i, j, 0, 0, this.imageWidth, 3 * 18 + 17);
graphics.blit(GuiEnderCrate.CHEST_GUI_TEXTURE, i, j + 3 * 18 + 17, 0, 126, this.imageWidth, 96);
}
}

View file

@ -36,10 +36,10 @@ public class ItemAuraBottle extends ItemImpl implements IColorProvidingItem, ICu
NeoForge.EVENT_BUS.register(new EventHandler());
DispenserBlock.registerBehavior(emptyBottle, (source, stack) -> {
Level level = source.getLevel();
var state = source.getBlockState();
Level level = source.level();
var state = source.state();
var facing = state.getValue(DispenserBlock.FACING);
var offset = source.getPos().relative(facing);
var offset = source.pos().relative(facing);
var offsetState = level.getBlockState(offset);
var dispense = stack.split(1);

View file

@ -9,7 +9,6 @@ import de.ellpeck.naturesaura.gui.ContainerEnderCrate;
import de.ellpeck.naturesaura.gui.ModContainers;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
@ -23,7 +22,6 @@ import net.minecraft.world.level.Level;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.network.NetworkHooks;
import javax.annotation.Nullable;
import java.util.List;
@ -42,7 +40,7 @@ public class ItemEnderAccess extends ItemImpl {
var name = BlockEnderCrate.getEnderName(stack);
if (!Strings.isNullOrEmpty(name)) {
if (!levelIn.isClientSide && NaturesAuraAPI.instance().extractAuraFromPlayer(playerIn, 10000, false)) {
NetworkHooks.openScreen((ServerPlayer) playerIn, new MenuProvider() {
playerIn.openMenu(new MenuProvider() {
@Override
public Component getDisplayName() {
return Component.translatable("info." + NaturesAura.MOD_ID + ".ender_access", ChatFormatting.ITALIC + name + ChatFormatting.RESET);
@ -66,4 +64,5 @@ public class ItemEnderAccess extends ItemImpl {
public void appendHoverText(ItemStack stack, @Nullable Level levelIn, List<Component> tooltip, TooltipFlag flagIn) {
BlockEnderCrate.addEnderNameInfo(stack, tooltip);
}
}

View file

@ -2,6 +2,7 @@ package de.ellpeck.naturesaura.items;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
@ -9,7 +10,6 @@ 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.Blocks;
import net.neoforged.neoforge.registries.ForgeRegistries;
public class ItemNetheriteFinder extends ItemImpl {
@ -35,7 +35,7 @@ public class ItemNetheriteFinder extends ItemImpl {
for (var z = -range; z <= range; z++) {
var offset = new BlockPos(pos.getX() + x, y, pos.getZ() + z);
var state = levelIn.getBlockState(offset);
if (state.getBlock() == Blocks.ANCIENT_DEBRIS || ForgeRegistries.BLOCKS.getKey(state.getBlock()).toString().contains("netherite")) {
if (state.getBlock() == Blocks.ANCIENT_DEBRIS || BuiltInRegistries.BLOCK.getKey(state.getBlock()).toString().contains("netherite")) {
inst.spawnMagicParticle(
offset.getX() + 0.5F, offset.getY() + 0.5F, offset.getZ() + 0.5F,
0F, 0F, 0F, 0xab4d38, 6F, 20 * 60, 0F, false, true);
@ -52,4 +52,5 @@ public class ItemNetheriteFinder extends ItemImpl {
playerIn.getCooldowns().addCooldown(this, 20 * 60);
return new InteractionResultHolder<>(InteractionResult.SUCCESS, stack);
}
}

View file

@ -16,12 +16,10 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.*;
import net.minecraft.world.phys.AABB;
import net.neoforged.neoforge.common.NeoForgeMod;
import net.neoforged.neoforge.common.capabilities.ICapabilityProvider;
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 net.neoforged.neoforge.registries.ForgeRegistries;
import javax.annotation.Nullable;
import java.util.Comparator;

View file

@ -1,10 +1,10 @@
package de.ellpeck.naturesaura.misc;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.neoforged.neoforge.registries.ForgeRegistries;
import java.util.Arrays;
import java.util.Comparator;
@ -24,7 +24,7 @@ public final class ColoredBlockHelper {
private static List<Block> collectBlocks(String name) {
return Arrays.stream(DyeColor.values()).sorted(Comparator.comparingInt(DyeColor::getId)).map(c -> {
var loc = new ResourceLocation(c.getName() + '_' + name);
var block = ForgeRegistries.BLOCKS.getValue(loc);
var block = BuiltInRegistries.BLOCK.get(loc);
if (block == null || block == Blocks.AIR)
throw new IllegalStateException("Couldn't find block with name " + loc);
return block;
@ -38,4 +38,5 @@ public final class ColoredBlockHelper {
}
return null;
}
}

View file

@ -3,7 +3,6 @@ package de.ellpeck.naturesaura.misc;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.misc.ILevelData;
import de.ellpeck.naturesaura.blocks.tiles.BlockEntitySpawnLamp;
import de.ellpeck.naturesaura.blocks.tiles.ItemStackHandlerNA;
@ -11,40 +10,47 @@ import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.items.ModItems;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.LongTag;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Tuple;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.saveddata.SavedData;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.common.capabilities.Capability;
import net.neoforged.neoforge.common.util.LazyOptional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
public class LevelData implements ILevelData {
public class LevelData extends SavedData implements ILevelData {
public static final SavedData.Factory<LevelData> FACTORY = new SavedData.Factory<>(LevelData::new, LevelData::new);
public static LevelData client;
public final ListMultimap<ResourceLocation, Tuple<Vec3, Integer>> effectPowders = ArrayListMultimap.create();
public final Long2ObjectOpenHashMap<AuraChunk> auraChunksWithSpots = new Long2ObjectOpenHashMap<>();
public final List<BlockPos> recentlyConvertedMossStones = new ArrayList<>();
public final Set<BlockEntitySpawnLamp> spawnLamps = new HashSet<>();
private final Map<String, ItemStackHandlerNA> enderStorages = new HashMap<>();
private final LazyOptional<LevelData> lazyThis = LazyOptional.of(() -> this);
@Nullable
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable Direction facing) {
return capability == NaturesAuraAPI.CAP_LEVEL_DATA ? this.lazyThis.cast() : LazyOptional.empty();
public Level level;
public LevelData() {
}
public LevelData(CompoundTag compound) {
for (var base : compound.getList("storages", 10)) {
var storageComp = (CompoundTag) base;
var storage = this.getEnderStorage(storageComp.getString("name"));
storage.deserializeNBT(storageComp);
}
for (var base : compound.getList("converted_moss", Tag.TAG_LONG))
this.recentlyConvertedMossStones.add(BlockPos.of(((LongTag) base).getAsLong()));
}
@Override
public CompoundTag serializeNBT() {
var compound = new CompoundTag();
public CompoundTag save(CompoundTag compound) {
var storages = new ListTag();
for (var entry : this.enderStorages.entrySet()) {
var handler = entry.getValue();
@ -64,20 +70,6 @@ public class LevelData implements ILevelData {
return compound;
}
@Override
public void deserializeNBT(CompoundTag compound) {
this.enderStorages.clear();
for (var base : compound.getList("storages", 10)) {
var storageComp = (CompoundTag) base;
var storage = this.getEnderStorage(storageComp.getString("name"));
storage.deserializeNBT(storageComp);
}
this.recentlyConvertedMossStones.clear();
for (var base : compound.getList("converted_moss", Tag.TAG_LONG))
this.recentlyConvertedMossStones.add(BlockPos.of(((LongTag) base).getAsLong()));
}
@Override
public ItemStackHandlerNA getEnderStorage(String name) {
return this.enderStorages.computeIfAbsent(name, n -> new ItemStackHandlerNA(27));
@ -99,4 +91,5 @@ public class LevelData implements ILevelData {
if (this.recentlyConvertedMossStones.size() > 512)
this.recentlyConvertedMossStones.remove(0);
}
}

View file

@ -5,18 +5,21 @@ import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.events.ClientEvents;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.network.NetworkEvent;
import net.neoforged.neoforge.network.handling.PlayPayloadContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Supplier;
public class PacketAuraChunk {
public class PacketAuraChunk implements CustomPacketPayload {
private int chunkX;
private int chunkZ;
private Collection<AuraChunk.DrainSpot> drainSpots;
public static final ResourceLocation ID = new ResourceLocation(NaturesAura.MOD_ID, "aura_chunk");
private final int chunkX;
private final int chunkZ;
private final Collection<AuraChunk.DrainSpot> drainSpots;
public PacketAuraChunk(int chunkX, int chunkZ, Collection<AuraChunk.DrainSpot> drainSpots) {
this.chunkX = chunkX;
@ -24,34 +27,33 @@ public class PacketAuraChunk {
this.drainSpots = drainSpots;
}
private PacketAuraChunk() {
}
public PacketAuraChunk(FriendlyByteBuf buf) {
this.chunkX = buf.readInt();
this.chunkZ = buf.readInt();
public static PacketAuraChunk fromBytes(FriendlyByteBuf buf) {
var packet = new PacketAuraChunk();
packet.chunkX = buf.readInt();
packet.chunkZ = buf.readInt();
packet.drainSpots = new ArrayList<>();
this.drainSpots = new ArrayList<>();
var amount = buf.readInt();
for (var i = 0; i < amount; i++)
packet.drainSpots.add(new AuraChunk.DrainSpot(buf.readNbt()));
return packet;
this.drainSpots.add(new AuraChunk.DrainSpot(buf.readNbt()));
}
public static void toBytes(PacketAuraChunk packet, FriendlyByteBuf buf) {
buf.writeInt(packet.chunkX);
buf.writeInt(packet.chunkZ);
@Override
public void write(FriendlyByteBuf buf) {
buf.writeInt(this.chunkX);
buf.writeInt(this.chunkZ);
buf.writeInt(packet.drainSpots.size());
for (var entry : packet.drainSpots)
buf.writeInt(this.drainSpots.size());
for (var entry : this.drainSpots)
buf.writeNbt(entry.serializeNBT());
}
public static void onMessage(PacketAuraChunk message, Supplier<NetworkEvent.Context> ctx) {
ctx.get().enqueueWork(() -> ClientEvents.PENDING_AURA_CHUNKS.add(message));
ctx.get().setPacketHandled(true);
@Override
public ResourceLocation id() {
return PacketAuraChunk.ID;
}
public static void onMessage(PacketAuraChunk message, PlayPayloadContext ctx) {
ctx.workHandler().execute(() -> ClientEvents.PENDING_AURA_CHUNKS.add(message));
}
public boolean tryHandle(Level level) {
@ -59,7 +61,7 @@ public class PacketAuraChunk {
var chunk = level.getChunk(this.chunkX, this.chunkZ);
if (chunk.isEmpty())
return false;
var auraChunk = (AuraChunk) chunk.getCapability(NaturesAuraAPI.CAP_AURA_CHUNK).orElse(null);
var auraChunk = (AuraChunk) chunk.getData(NaturesAuraAPI.AURA_CHUNK_ATTACHMENT).get(chunk);
if (auraChunk == null)
return false;
auraChunk.setSpots(this.drainSpots);
@ -69,4 +71,5 @@ public class PacketAuraChunk {
return true;
}
}
}

View file

@ -1,5 +1,6 @@
package de.ellpeck.naturesaura.packet;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.items.ItemRangeVisualizer;
import de.ellpeck.naturesaura.items.ModItems;
import net.minecraft.client.Minecraft;
@ -7,63 +8,59 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.network.NetworkEvent;
import net.neoforged.neoforge.network.handling.PlayPayloadContext;
import java.util.function.Supplier;
public class PacketClient implements CustomPacketPayload {
public class PacketClient {
public static final ResourceLocation ID = new ResourceLocation(NaturesAura.MOD_ID, "client");
private int type;
private CompoundTag data;
private final int type;
private final CompoundTag data;
public PacketClient(int type, CompoundTag data) {
this.type = type;
this.data = data;
}
private PacketClient() {
public PacketClient(FriendlyByteBuf buf) {
this.type = buf.readByte();
this.data = buf.readNbt();
}
public static PacketClient fromBytes(FriendlyByteBuf buf) {
var client = new PacketClient();
client.type = buf.readByte();
client.data = buf.readNbt();
return client;
@Override
public void write(FriendlyByteBuf buf) {
buf.writeByte(this.type);
buf.writeNbt(this.data);
}
public static void toBytes(PacketClient packet, FriendlyByteBuf buf) {
buf.writeByte(packet.type);
buf.writeNbt(packet.data);
@Override
public ResourceLocation id() {
return PacketClient.ID;
}
// lambda causes classloading issues on a server here
@SuppressWarnings("Convert2Lambda")
public static void onMessage(PacketClient message, Supplier<NetworkEvent.Context> ctx) {
ctx.get().enqueueWork(new Runnable() {
@Override
public void run() {
var mc = Minecraft.getInstance();
if (mc.level != null) {
switch (message.type) {
case 0: // dimension rail visualization
var goalDim = new ResourceLocation(message.data.getString("dim"));
var goalPos = BlockPos.of(message.data.getLong("pos"));
ItemRangeVisualizer.visualize(mc.player, ItemRangeVisualizer.VISUALIZED_RAILS, goalDim, goalPos);
case 1:
var entity = mc.level.getEntity(message.data.getInt("id"));
mc.particleEngine.createTrackingEmitter(entity, ParticleTypes.TOTEM_OF_UNDYING, 30);
mc.level.playLocalSound(entity.getX(), entity.getY(), entity.getZ(), SoundEvents.TOTEM_USE, entity.getSoundSource(), 1.0F, 1.0F, false);
if (entity == mc.player) {
mc.gameRenderer.displayItemActivation(new ItemStack(ModItems.DEATH_RING));
}
}
public static void onMessage(PacketClient message, PlayPayloadContext ctx) {
ctx.workHandler().execute(() -> {
var mc = Minecraft.getInstance();
if (mc.level != null) {
switch (message.type) {
case 0: // dimension rail visualization
var goalDim = new ResourceLocation(message.data.getString("dim"));
var goalPos = BlockPos.of(message.data.getLong("pos"));
ItemRangeVisualizer.visualize(mc.player, ItemRangeVisualizer.VISUALIZED_RAILS, goalDim, goalPos);
case 1:
var entity = mc.level.getEntity(message.data.getInt("id"));
mc.particleEngine.createTrackingEmitter(entity, ParticleTypes.TOTEM_OF_UNDYING, 30);
mc.level.playLocalSound(entity.getX(), entity.getY(), entity.getZ(), SoundEvents.TOTEM_USE, entity.getSoundSource(), 1.0F, 1.0F, false);
if (entity == mc.player) {
mc.gameRenderer.displayItemActivation(new ItemStack(ModItems.DEATH_RING));
}
}
}
});
ctx.get().setPacketHandled(true);
}
}

View file

@ -2,36 +2,37 @@ package de.ellpeck.naturesaura.packet;
import de.ellpeck.naturesaura.NaturesAura;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
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.neoforge.network.PacketDistributor;
import net.neoforged.neoforge.network.simple.SimpleChannel;
import net.neoforged.neoforge.network.NetworkRegistry;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent;
@Mod.EventBusSubscriber
public final class PacketHandler {
private static final String VERSION = "1";
private static SimpleChannel network;
public static void init() {
PacketHandler.network = NetworkRegistry.newSimpleChannel(new ResourceLocation(NaturesAura.MOD_ID, "network"), () -> PacketHandler.VERSION, PacketHandler.VERSION::equals, PacketHandler.VERSION::equals);
PacketHandler.network.registerMessage(0, PacketParticleStream.class, PacketParticleStream::toBytes, PacketParticleStream::fromBytes, PacketParticleStream::onMessage);
PacketHandler.network.registerMessage(1, PacketParticles.class, PacketParticles::toBytes, PacketParticles::fromBytes, PacketParticles::onMessage);
PacketHandler.network.registerMessage(2, PacketAuraChunk.class, PacketAuraChunk::toBytes, PacketAuraChunk::fromBytes, PacketAuraChunk::onMessage);
PacketHandler.network.registerMessage(3, PacketClient.class, PacketClient::toBytes, PacketClient::fromBytes, PacketClient::onMessage);
@SubscribeEvent
public static void onPayloadRegister(RegisterPayloadHandlerEvent event) {
var registrar = event.registrar(NaturesAura.MOD_ID);
registrar.play(PacketAuraChunk.ID, PacketAuraChunk::new, PacketAuraChunk::onMessage);
registrar.play(PacketClient.ID, PacketClient::new, PacketClient::onMessage);
registrar.play(PacketParticles.ID, PacketParticles::new, PacketParticles::onMessage);
registrar.play(PacketParticleStream.ID, PacketParticleStream::new, PacketParticleStream::onMessage);
}
public static void sendToAllLoaded(Level level, BlockPos pos, Object message) {
PacketHandler.network.send(PacketDistributor.TRACKING_CHUNK.with(() -> level.getChunkAt(pos)), message);
public static void sendToAllLoaded(Level level, BlockPos pos, CustomPacketPayload message) {
PacketDistributor.TRACKING_CHUNK.with(level.getChunkAt(pos)).send(message);
}
public static void sendToAllAround(Level level, BlockPos pos, int range, Object message) {
PacketHandler.network.send(PacketDistributor.NEAR.with(() -> new PacketDistributor.TargetPoint(pos.getX(), pos.getY(), pos.getZ(), range, level.dimension())), message);
public static void sendToAllAround(Level level, BlockPos pos, int range, CustomPacketPayload message) {
PacketDistributor.NEAR.with(new PacketDistributor.TargetPoint(pos.getX(), pos.getY(), pos.getZ(), range, level.dimension())).send(message);
}
public static void sendTo(Player player, Object message) {
PacketHandler.network.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), message);
public static void sendTo(Player player, CustomPacketPayload message) {
((ServerPlayer) player).connection.send(message);
}
}

View file

@ -1,24 +1,27 @@
package de.ellpeck.naturesaura.packet;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import net.minecraft.network.FriendlyByteBuf;
import net.neoforged.neoforge.network.NetworkEvent;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.neoforge.network.handling.PlayPayloadContext;
import java.util.function.Supplier;
public class PacketParticleStream implements CustomPacketPayload {
public class PacketParticleStream {
public static final ResourceLocation ID = new ResourceLocation(NaturesAura.MOD_ID, "particle_stream");
private float startX;
private float startY;
private float startZ;
private final float startX;
private final float startY;
private final float startZ;
private float endX;
private float endY;
private float endZ;
private final float endX;
private final float endY;
private final float endZ;
private float speed;
private int color;
private float scale;
private final float speed;
private final int color;
private final float scale;
public PacketParticleStream(float startX, float startY, float startZ, float endX, float endY, float endZ, float speed, int color, float scale) {
this.startX = startX;
@ -32,43 +35,41 @@ public class PacketParticleStream {
this.scale = scale;
}
private PacketParticleStream() {
public PacketParticleStream(FriendlyByteBuf buf) {
this.startX = buf.readFloat();
this.startY = buf.readFloat();
this.startZ = buf.readFloat();
this.endX = buf.readFloat();
this.endY = buf.readFloat();
this.endZ = buf.readFloat();
this.speed = buf.readFloat();
this.color = buf.readInt();
this.scale = buf.readFloat();
}
public static PacketParticleStream fromBytes(FriendlyByteBuf buf) {
var packet = new PacketParticleStream();
packet.startX = buf.readFloat();
packet.startY = buf.readFloat();
packet.startZ = buf.readFloat();
packet.endX = buf.readFloat();
packet.endY = buf.readFloat();
packet.endZ = buf.readFloat();
packet.speed = buf.readFloat();
packet.color = buf.readInt();
packet.scale = buf.readFloat();
return packet;
@Override
public void write(FriendlyByteBuf buf) {
buf.writeFloat(this.startX);
buf.writeFloat(this.startY);
buf.writeFloat(this.startZ);
buf.writeFloat(this.endX);
buf.writeFloat(this.endY);
buf.writeFloat(this.endZ);
buf.writeFloat(this.speed);
buf.writeInt(this.color);
buf.writeFloat(this.scale);
}
public static void toBytes(PacketParticleStream packet, FriendlyByteBuf buf) {
buf.writeFloat(packet.startX);
buf.writeFloat(packet.startY);
buf.writeFloat(packet.startZ);
buf.writeFloat(packet.endX);
buf.writeFloat(packet.endY);
buf.writeFloat(packet.endZ);
buf.writeFloat(packet.speed);
buf.writeInt(packet.color);
buf.writeFloat(packet.scale);
@Override
public ResourceLocation id() {
return PacketParticleStream.ID;
}
public static void onMessage(PacketParticleStream message, Supplier<NetworkEvent.Context> ctx) {
ctx.get().enqueueWork(() -> NaturesAuraAPI.instance().spawnParticleStream(
public static void onMessage(PacketParticleStream message, PlayPayloadContext ctx) {
ctx.workHandler().execute(() -> NaturesAuraAPI.instance().spawnParticleStream(
message.startX, message.startY, message.startZ,
message.endX, message.endY, message.endZ,
message.speed, message.color, message.scale));
ctx.get().setPacketHandled(true);
}
}

View file

@ -1,5 +1,6 @@
package de.ellpeck.naturesaura.packet;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
@ -11,19 +12,22 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ItemParticleOption;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.network.NetworkEvent;
import net.neoforged.neoforge.network.handling.PlayPayloadContext;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
public class PacketParticles {
public class PacketParticles implements CustomPacketPayload {
private float posX;
private float posY;
private float posZ;
private Type type;
private int[] data;
public static final ResourceLocation ID = new ResourceLocation(NaturesAura.MOD_ID, "particles");
private final float posX;
private final float posY;
private final float posZ;
private final Type type;
private final int[] data;
public PacketParticles(float posX, float posY, float posZ, Type type, int... data) {
this.posX = posX;
@ -33,49 +37,40 @@ public class PacketParticles {
this.data = data;
}
private PacketParticles() {
public PacketParticles(FriendlyByteBuf buf) {
this.posX = buf.readFloat();
this.posY = buf.readFloat();
this.posZ = buf.readFloat();
this.type = Type.values()[buf.readByte()];
this.data = new int[buf.readByte()];
for (var i = 0; i < this.data.length; i++)
this.data[i] = buf.readInt();
}
public static PacketParticles fromBytes(FriendlyByteBuf buf) {
var packet = new PacketParticles();
@Override
public void write(FriendlyByteBuf buf) {
buf.writeFloat(this.posX);
buf.writeFloat(this.posY);
buf.writeFloat(this.posZ);
buf.writeByte(this.type.ordinal());
packet.posX = buf.readFloat();
packet.posY = buf.readFloat();
packet.posZ = buf.readFloat();
packet.type = Type.values()[buf.readByte()];
packet.data = new int[buf.readByte()];
for (var i = 0; i < packet.data.length; i++) {
packet.data[i] = buf.readInt();
}
return packet;
}
public static void toBytes(PacketParticles packet, FriendlyByteBuf buf) {
buf.writeFloat(packet.posX);
buf.writeFloat(packet.posY);
buf.writeFloat(packet.posZ);
buf.writeByte(packet.type.ordinal());
buf.writeByte(packet.data.length);
for (var i : packet.data) {
buf.writeByte(this.data.length);
for (var i : this.data)
buf.writeInt(i);
}
}
// lambda causes classloading issues on a server here
@SuppressWarnings("Convert2Lambda")
public static void onMessage(PacketParticles message, Supplier<NetworkEvent.Context> ctx) {
ctx.get().enqueueWork(new Runnable() {
@Override
public void run() {
Level level = Minecraft.getInstance().level;
if (level != null)
message.type.action.accept(message, level);
}
@Override
public ResourceLocation id() {
return null;
}
public static void onMessage(PacketParticles message, PlayPayloadContext ctx) {
ctx.workHandler().execute(() -> {
Level level = Minecraft.getInstance().level;
if (level != null)
message.type.action.accept(message, level);
});
ctx.get().setPacketHandled(true);
}
public enum Type {
@ -578,4 +573,5 @@ public class PacketParticles {
this.action = action;
}
}
}

View file

@ -1,14 +1,13 @@
package de.ellpeck.naturesaura.recipes;
import com.google.gson.JsonObject;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.RegistryAccess;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.item.crafting.RecipeType;
import net.neoforged.neoforge.common.crafting.CraftingHelper;
import javax.annotation.Nullable;
@ -20,8 +19,7 @@ public class AltarRecipe extends ModRecipe {
public final int aura;
public final int time;
public AltarRecipe(ResourceLocation name, Ingredient input, ItemStack output, Ingredient catalyst, int aura, int time) {
super(name);
public AltarRecipe(Ingredient input, ItemStack output, Ingredient catalyst, int aura, int time) {
this.input = input;
this.output = output;
this.catalyst = catalyst;
@ -46,27 +44,23 @@ public class AltarRecipe extends ModRecipe {
public static class Serializer implements RecipeSerializer<AltarRecipe> {
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),
Codec.INT.fieldOf("aura").forGetter(r -> r.aura),
Codec.INT.fieldOf("time").forGetter(r -> r.time)
).apply(i, AltarRecipe::new));
@Override
public AltarRecipe fromJson(ResourceLocation recipeId, JsonObject json) {
return new AltarRecipe(
recipeId,
Ingredient.fromJson(json.getAsJsonObject("input")),
CraftingHelper.getItemStack(json.getAsJsonObject("output"), true),
json.has("catalyst") ? Ingredient.fromJson(json.getAsJsonObject("catalyst")) : Ingredient.EMPTY,
json.get("aura").getAsInt(),
json.get("time").getAsInt());
public Codec<AltarRecipe> codec() {
return Serializer.CODEC;
}
@Nullable
@Override
public AltarRecipe fromNetwork(ResourceLocation recipeId, FriendlyByteBuf buffer) {
return new AltarRecipe(
recipeId,
Ingredient.fromNetwork(buffer),
buffer.readItem(),
Ingredient.fromNetwork(buffer),
buffer.readInt(),
buffer.readInt());
public AltarRecipe fromNetwork(FriendlyByteBuf buffer) {
return new AltarRecipe(Ingredient.fromNetwork(buffer), buffer.readItem(), Ingredient.fromNetwork(buffer), buffer.readInt(), buffer.readInt());
}
@Override
@ -77,5 +71,7 @@ public class AltarRecipe extends ModRecipe {
buffer.writeInt(recipe.aura);
buffer.writeInt(recipe.time);
}
}
}

View file

@ -1,8 +1,10 @@
package de.ellpeck.naturesaura.recipes;
import com.google.gson.JsonObject;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.BlockPos;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
@ -14,23 +16,20 @@ import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.registries.ForgeRegistries;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class AnimalSpawnerRecipe extends ModRecipe {
public final Ingredient[] ingredients;
public final List<Ingredient> ingredients;
public final EntityType<?> entity;
public final int aura;
public final int time;
public AnimalSpawnerRecipe(ResourceLocation name, EntityType<?> entity, int aura, int time, Ingredient... ingredients) {
super(name);
public AnimalSpawnerRecipe(ResourceLocation entityType, int aura, int time, List<Ingredient> ingredients) {
this.ingredients = ingredients;
this.entity = entity;
this.entity = BuiltInRegistries.ENTITY_TYPE.get(entityType);
this.aura = aura;
this.time = time;
}
@ -59,40 +58,36 @@ public class AnimalSpawnerRecipe extends ModRecipe {
public static class Serializer implements RecipeSerializer<AnimalSpawnerRecipe> {
private static final Codec<AnimalSpawnerRecipe> CODEC = RecordCodecBuilder.create(i -> i.group(
ResourceLocation.CODEC.fieldOf("entity").forGetter(r -> BuiltInRegistries.ENTITY_TYPE.getKey(r.entity)),
Codec.INT.fieldOf("aura").forGetter(r -> r.aura),
Codec.INT.fieldOf("time").forGetter(r -> r.time),
Ingredient.CODEC.listOf().fieldOf("ingredients").forGetter(r -> r.ingredients)
).apply(i, AnimalSpawnerRecipe::new));
@Override
public AnimalSpawnerRecipe fromJson(ResourceLocation recipeId, JsonObject json) {
List<Ingredient> ingredients = new ArrayList<>();
for (var e : json.getAsJsonArray("ingredients"))
ingredients.add(Ingredient.fromJson(e));
return new AnimalSpawnerRecipe(recipeId,
ForgeRegistries.ENTITY_TYPES.getValue(new ResourceLocation(json.get("entity").getAsString())),
json.get("aura").getAsInt(),
json.get("time").getAsInt(),
ingredients.toArray(new Ingredient[0]));
public Codec<AnimalSpawnerRecipe> codec() {
return Serializer.CODEC;
}
@Nullable
@Override
public AnimalSpawnerRecipe fromNetwork(ResourceLocation recipeId, FriendlyByteBuf buffer) {
var ings = new Ingredient[buffer.readInt()];
for (var i = 0; i < ings.length; i++)
ings[i] = Ingredient.fromNetwork(buffer);
return new AnimalSpawnerRecipe(
recipeId,
ForgeRegistries.ENTITY_TYPES.getValue(buffer.readResourceLocation()),
buffer.readInt(),
buffer.readInt(),
ings);
public AnimalSpawnerRecipe fromNetwork(FriendlyByteBuf buffer) {
var ingredients = new ArrayList<Ingredient>();
for (var i = buffer.readInt(); i > 0; i--)
ingredients.add(Ingredient.fromNetwork(buffer));
return new AnimalSpawnerRecipe(buffer.readResourceLocation(), buffer.readInt(), buffer.readInt(), ingredients);
}
@Override
public void toNetwork(FriendlyByteBuf buffer, AnimalSpawnerRecipe recipe) {
buffer.writeInt(recipe.ingredients.length);
buffer.writeInt(recipe.ingredients.size());
for (var ing : recipe.ingredients)
ing.toNetwork(buffer);
buffer.writeResourceLocation(ForgeRegistries.ENTITY_TYPES.getKey(recipe.entity));
buffer.writeResourceLocation(BuiltInRegistries.ENTITY_TYPE.getKey(recipe.entity));
buffer.writeInt(recipe.aura);
buffer.writeInt(recipe.time);
}
}
}

View file

@ -1,17 +1,18 @@
package de.ellpeck.naturesaura.recipes;
import com.google.gson.JsonObject;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.ellpeck.naturesaura.ModConfig;
import de.ellpeck.naturesaura.NaturesAura;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.GsonHelper;
import net.neoforged.neoforge.common.ModConfigSpec;
import net.neoforged.neoforge.common.crafting.conditions.ICondition;
import net.neoforged.neoforge.common.crafting.conditions.IConditionSerializer;
import net.neoforged.neoforge.common.conditions.ICondition;
public class EnabledCondition implements ICondition {
private static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "enabled");
private static final Codec<EnabledCondition> CODEC = RecordCodecBuilder.create(i ->
i.group(Codec.STRING.fieldOf("name").forGetter(c -> c.name)).apply(i, EnabledCondition::new)
);
private ModConfigSpec.ConfigValue<Boolean> config;
private final String name;
@ -25,31 +26,14 @@ public class EnabledCondition implements ICondition {
}
}
@Override
public ResourceLocation getID() {
return EnabledCondition.NAME;
}
@Override
public boolean test(IContext context) {
return this.config != null && this.config.get();
}
public static class Serializer implements IConditionSerializer<EnabledCondition> {
@Override
public void write(JsonObject json, EnabledCondition value) {
json.addProperty("config", value.name);
}
@Override
public EnabledCondition read(JsonObject json) {
return new EnabledCondition(GsonHelper.getAsString(json, "config"));
}
@Override
public ResourceLocation getID() {
return EnabledCondition.NAME;
}
@Override
public Codec<? extends ICondition> codec() {
return EnabledCondition.CODEC;
}
}

View file

@ -1,7 +1,6 @@
package de.ellpeck.naturesaura.recipes;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.level.Level;
@ -9,12 +8,6 @@ import net.neoforged.neoforge.items.wrapper.RecipeWrapper;
public abstract class ModRecipe implements Recipe<RecipeWrapper> {
public final ResourceLocation name;
public ModRecipe(ResourceLocation name) {
this.name = name;
}
@Override
public boolean matches(RecipeWrapper inv, Level levelIn) {
// return true here so that we can easily get all recipes of a type from the recipe manager
@ -31,9 +24,5 @@ public abstract class ModRecipe implements Recipe<RecipeWrapper> {
return false;
}
@Override
public ResourceLocation getId() {
return this.name;
}
}

View file

@ -3,6 +3,7 @@ package de.ellpeck.naturesaura.recipes;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.misc.WeatherType;
import de.ellpeck.naturesaura.api.misc.WeightedOre;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.item.ItemStack;
@ -10,7 +11,6 @@ import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.level.block.Blocks;
import net.neoforged.neoforge.registries.ForgeRegistries;
import java.util.List;
@ -115,11 +115,13 @@ public final class ModRecipes {
list.add(new WeightedOre(res, weight));
}
private static class RecipeType<T extends Recipe<?>> implements net.minecraft.world.item.crafting.RecipeType<T> {
public static class RecipeType<T extends Recipe<?>> implements net.minecraft.world.item.crafting.RecipeType<T> {
@Override
public String toString() {
return ForgeRegistries.RECIPE_TYPES.getKey(this).toString();
return BuiltInRegistries.RECIPE_TYPE.getKey(this).toString();
}
}
}

View file

@ -1,14 +1,13 @@
package de.ellpeck.naturesaura.recipes;
import com.google.gson.JsonObject;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.RegistryAccess;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.item.crafting.RecipeType;
import net.neoforged.neoforge.common.crafting.CraftingHelper;
import javax.annotation.Nullable;
@ -18,8 +17,7 @@ public class OfferingRecipe extends ModRecipe {
public final Ingredient startItem;
public final ItemStack output;
public OfferingRecipe(ResourceLocation name, Ingredient input, Ingredient startItem, ItemStack output) {
super(name);
public OfferingRecipe(Ingredient input, Ingredient startItem, ItemStack output) {
this.input = input;
this.startItem = startItem;
this.output = output;
@ -42,23 +40,21 @@ public class OfferingRecipe extends ModRecipe {
public static class Serializer implements RecipeSerializer<OfferingRecipe> {
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)
).apply(i, OfferingRecipe::new));
@Override
public OfferingRecipe fromJson(ResourceLocation recipeId, JsonObject json) {
return new OfferingRecipe(
recipeId,
Ingredient.fromJson(json.get("input")),
Ingredient.fromJson(json.get("start_item")),
CraftingHelper.getItemStack(json.getAsJsonObject("output"), true));
public Codec<OfferingRecipe> codec() {
return Serializer.CODEC;
}
@Nullable
@Override
public OfferingRecipe fromNetwork(ResourceLocation recipeId, FriendlyByteBuf buffer) {
return new OfferingRecipe(
recipeId,
Ingredient.fromNetwork(buffer),
Ingredient.fromNetwork(buffer),
buffer.readItem());
public OfferingRecipe fromNetwork(FriendlyByteBuf buffer) {
return new OfferingRecipe(Ingredient.fromNetwork(buffer), Ingredient.fromNetwork(buffer), buffer.readItem());
}
@Override
@ -67,5 +63,7 @@ public class OfferingRecipe extends ModRecipe {
recipe.startItem.toNetwork(buffer);
buffer.writeItem(recipe.output);
}
}
}

View file

@ -1,14 +1,13 @@
package de.ellpeck.naturesaura.recipes;
import com.google.gson.JsonObject;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.RegistryAccess;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.item.crafting.RecipeType;
import net.neoforged.neoforge.common.crafting.CraftingHelper;
import javax.annotation.Nullable;
import java.util.ArrayList;
@ -17,12 +16,11 @@ import java.util.List;
public class TreeRitualRecipe extends ModRecipe {
public final Ingredient saplingType;
public final Ingredient[] ingredients;
public final List<Ingredient> ingredients;
public final ItemStack result;
public final int time;
public TreeRitualRecipe(ResourceLocation name, Ingredient saplingType, ItemStack result, int time, Ingredient... ingredients) {
super(name);
public TreeRitualRecipe(Ingredient saplingType, ItemStack result, int time, List<Ingredient> ingredients) {
this.saplingType = saplingType;
this.ingredients = ingredients;
this.result = result;
@ -46,41 +44,37 @@ public class TreeRitualRecipe extends ModRecipe {
public static class Serializer implements RecipeSerializer<TreeRitualRecipe> {
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),
Codec.INT.fieldOf("time").forGetter(r -> r.time),
Ingredient.CODEC.listOf().fieldOf("ingredients").forGetter(recipe -> recipe.ingredients)
).apply(i, TreeRitualRecipe::new));
@Override
public TreeRitualRecipe fromJson(ResourceLocation recipeId, JsonObject json) {
List<Ingredient> ings = new ArrayList<>();
for (var element : json.getAsJsonArray("ingredients"))
ings.add(Ingredient.fromJson(element));
return new TreeRitualRecipe(
recipeId,
Ingredient.fromJson(json.getAsJsonObject("sapling")),
CraftingHelper.getItemStack(json.getAsJsonObject("output"), true),
json.get("time").getAsInt(),
ings.toArray(new Ingredient[0]));
public Codec<TreeRitualRecipe> codec() {
return Serializer.CODEC;
}
@Nullable
@Override
public TreeRitualRecipe fromNetwork(ResourceLocation recipeId, FriendlyByteBuf buffer) {
var ings = new Ingredient[buffer.readInt()];
for (var i = 0; i < ings.length; i++)
ings[i] = Ingredient.fromNetwork(buffer);
return new TreeRitualRecipe(
recipeId,
Ingredient.fromNetwork(buffer),
buffer.readItem(),
buffer.readInt(),
ings);
public TreeRitualRecipe fromNetwork(FriendlyByteBuf buffer) {
var ingredients = new ArrayList<Ingredient>();
for (var i = buffer.readInt(); i > 0; i--)
ingredients.add(Ingredient.fromNetwork(buffer));
return new TreeRitualRecipe(Ingredient.fromNetwork(buffer), buffer.readItem(), buffer.readInt(), ingredients);
}
@Override
public void toNetwork(FriendlyByteBuf buffer, TreeRitualRecipe recipe) {
buffer.writeInt(recipe.ingredients.length);
buffer.writeInt(recipe.ingredients.size());
for (var ing : recipe.ingredients)
ing.toNetwork(buffer);
recipe.saplingType.toNetwork(buffer);
buffer.writeItem(recipe.result);
buffer.writeInt(recipe.time);
}
}
}

View file

@ -2,6 +2,7 @@ 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.misc.ILevelData;
import de.ellpeck.naturesaura.blocks.*;
import de.ellpeck.naturesaura.blocks.tiles.BlockEntityAuraBloom;
@ -21,9 +22,9 @@ import de.ellpeck.naturesaura.items.*;
import de.ellpeck.naturesaura.items.tools.*;
import de.ellpeck.naturesaura.potion.ModPotions;
import de.ellpeck.naturesaura.potion.PotionBreathless;
import de.ellpeck.naturesaura.recipes.EnabledCondition;
import de.ellpeck.naturesaura.recipes.ModRecipes;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EntityType;
@ -36,13 +37,16 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.FlowerPotBlock;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.levelgen.structure.BuiltinStructures;
import net.neoforged.neoforge.common.crafting.CraftingHelper;
import net.neoforged.neoforge.common.extensions.IMenuTypeExtension;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.capabilities.Capabilities.EnergyStorage;
import net.neoforged.neoforge.capabilities.Capabilities.FluidHandler;
import net.neoforged.neoforge.capabilities.Capabilities.ItemHandler;
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
import net.neoforged.neoforge.common.extensions.IMenuTypeExtension;
import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
import net.neoforged.neoforge.registries.RegisterEvent;
import net.neoforged.neoforge.registries.ForgeRegistries;
import vazkii.patchouli.api.PatchouliAPI;
import java.util.ArrayList;
@ -56,14 +60,14 @@ public final class ModRegistry {
@SubscribeEvent
public static void register(RegisterEvent event) {
event.register(ForgeRegistries.Keys.BLOCKS, h -> {
event.register(Registries.BLOCK, h -> {
Block temp;
ModRegistry.registerAll(h,
new BlockAncientLog("ancient_log"),
new BlockAncientLog("ancient_bark"),
temp = new BlockImpl("ancient_planks", Block.Properties.of().sound(SoundType.WOOD).strength(2F)),
new BlockStairsNA("ancient_stairs", "ancient_planks", temp::defaultBlockState, Block.Properties.copy(temp)),
new Slab("ancient_slab", "ancient_planks", Block.Properties.copy(temp)),
new BlockStairsNA("ancient_stairs", "ancient_planks", temp::defaultBlockState, Block.Properties.ofFullCopy(temp)),
new Slab("ancient_slab", "ancient_planks", Block.Properties.ofFullCopy(temp)),
new BlockAncientLeaves(),
new BlockAncientSapling(),
new BlockNatureAltar(),
@ -72,11 +76,11 @@ public final class ModRegistry {
new BlockGoldPowder(),
new BlockWoodStand(),
temp = new BlockImpl("infused_stone", Block.Properties.of().sound(SoundType.STONE).strength(1.75F)),
new BlockStairsNA("infused_stairs", "infused_stone", temp::defaultBlockState, Block.Properties.copy(temp)),
new Slab("infused_slab", "infused_stone", Block.Properties.copy(temp)),
new BlockStairsNA("infused_stairs", "infused_stone", temp::defaultBlockState, Block.Properties.ofFullCopy(temp)),
new Slab("infused_slab", "infused_stone", Block.Properties.ofFullCopy(temp)),
temp = new BlockImpl("infused_brick", Block.Properties.of().sound(SoundType.STONE).strength(1.5F)),
new BlockStairsNA("infused_brick_stairs", "infused_brick", temp::defaultBlockState, Block.Properties.copy(temp)),
new Slab("infused_brick_slab", "infused_brick", Block.Properties.copy(temp)),
new BlockStairsNA("infused_brick_stairs", "infused_brick", temp::defaultBlockState, Block.Properties.ofFullCopy(temp)),
new Slab("infused_brick_slab", "infused_brick", Block.Properties.ofFullCopy(temp)),
new BlockFurnaceHeater(),
new BlockPotionGenerator(),
new BlockAuraDetector(),
@ -96,8 +100,8 @@ public final class ModRegistry {
new BlockGratedChute(),
new BlockAnimalSpawner(),
new BlockAutoCrafter(),
new BlockImpl("gold_brick", Block.Properties.copy(Blocks.STONE_BRICKS)),
new BlockImpl("gold_nether_brick", Block.Properties.copy(Blocks.NETHER_BRICKS)),
new BlockImpl("gold_brick", Block.Properties.ofFullCopy(Blocks.STONE_BRICKS)),
new BlockImpl("gold_nether_brick", Block.Properties.ofFullCopy(Blocks.NETHER_BRICKS)),
new BlockMossGenerator(),
new BlockTimeChanger(),
new BlockGeneratorLimitRemover(),
@ -109,7 +113,7 @@ public final class ModRegistry {
new BlockDimensionRail("nether", Level.NETHER, Level.OVERWORLD),
new BlockDimensionRail("end", Level.END, Level.OVERWORLD),
new BlockBlastFurnaceBooster(),
new BlockImpl("nether_wart_mushroom", Block.Properties.copy(Blocks.RED_MUSHROOM_BLOCK)),
new BlockImpl("nether_wart_mushroom", Block.Properties.ofFullCopy(Blocks.RED_MUSHROOM_BLOCK)),
new BlockAnimalContainer(),
new BlockSnowCreator(),
new BlockItemDistributor(),
@ -137,10 +141,10 @@ public final class ModRegistry {
new BlockImpl("sky_ingot_block", Block.Properties.of().sound(SoundType.METAL).strength(4F)),
new BlockImpl("depth_ingot_block", Block.Properties.of().sound(SoundType.METAL).strength(6F))
);
Helper.populateObjectHolders(ModBlocks.class, event.getForgeRegistry());
Helper.populateObjectHolders(ModBlocks.class, BuiltInRegistries.BLOCK);
});
event.register(ForgeRegistries.Keys.ITEMS, h -> {
event.register(Registries.ITEM, h -> {
for (var block : ModRegistry.ALL_ITEMS) {
if (block instanceof Block && !(block instanceof INoItemBlock)) {
var item = new BlockItem((Block) block, new Item.Properties());
@ -222,10 +226,10 @@ public final class ModRegistry {
new ItemArmor("depth_pants", ModArmorMaterial.DEPTH, ArmorItem.Type.LEGGINGS),
new ItemArmor("depth_shoes", ModArmorMaterial.DEPTH, ArmorItem.Type.BOOTS)
);
Helper.populateObjectHolders(ModItems.class, event.getForgeRegistry());
Helper.populateObjectHolders(ModItems.class, BuiltInRegistries.ITEM);
});
event.register(ForgeRegistries.Keys.BLOCK_ENTITY_TYPES, h -> {
event.register(Registries.BLOCK_ENTITY_TYPE, h -> {
// add tile entities that support multiple blocks
ModRegistry.ALL_ITEMS.add(new ModTileType<>(BlockEntityAuraBloom::new, "aura_bloom", ModRegistry.ALL_ITEMS.stream().filter(i -> i instanceof BlockAuraBloom).toArray(IModItem[]::new)));
@ -233,15 +237,15 @@ public final class ModRegistry {
if (item instanceof ModTileType<?> type)
h.register(new ResourceLocation(NaturesAura.MOD_ID, type.getBaseName()), type.type);
}
Helper.populateObjectHolders(ModBlockEntities.class, event.getForgeRegistry());
Helper.populateObjectHolders(ModBlockEntities.class, BuiltInRegistries.BLOCK_ENTITY_TYPE);
});
event.register(ForgeRegistries.Keys.MOB_EFFECTS, h -> {
event.register(Registries.MOB_EFFECT, h -> {
h.register(new ResourceLocation(NaturesAura.MOD_ID, "breathless"), new PotionBreathless());
Helper.populateObjectHolders(ModPotions.class, event.getForgeRegistry());
Helper.populateObjectHolders(ModPotions.class, BuiltInRegistries.MOB_EFFECT);
});
event.register(ForgeRegistries.Keys.MENU_TYPES, h -> {
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)
@ -252,15 +256,15 @@ public final class ModRegistry {
IItemHandler handler = ILevelData.getOverworldData(inv.player.level()).getEnderStorage(data.readUtf());
return new ContainerEnderCrate(ModContainers.ENDER_ACCESS, windowId, inv.player, handler);
}));
Helper.populateObjectHolders(ModContainers.class, event.getForgeRegistry());
Helper.populateObjectHolders(ModContainers.class, BuiltInRegistries.MENU);
});
event.register(ForgeRegistries.Keys.ENCHANTMENTS, h -> {
event.register(Registries.ENCHANTMENT, h -> {
h.register(new ResourceLocation(NaturesAura.MOD_ID, "aura_mending"), new AuraMendingEnchantment());
Helper.populateObjectHolders(ModEnchantments.class, event.getForgeRegistry());
Helper.populateObjectHolders(ModEnchantments.class, BuiltInRegistries.ENCHANTMENT);
});
event.register(ForgeRegistries.Keys.ENTITY_TYPES, h -> {
event.register(Registries.ENTITY_TYPE, h -> {
h.register(new ResourceLocation(NaturesAura.MOD_ID, "mover_cart"), EntityType.Builder
.of(EntityMoverMinecart::new, MobCategory.MISC)
.sized(1, 1).setShouldReceiveVelocityUpdates(true)
@ -277,11 +281,10 @@ public final class ModRegistry {
.of(EntityStructureFinder::new, MobCategory.MISC)
.sized(0.5F, 0.5F).setShouldReceiveVelocityUpdates(true)
.setTrackingRange(64).setUpdateInterval(2).fireImmune().build(NaturesAura.MOD_ID + ":structure_finder"));
Helper.populateObjectHolders(ModEntities.class, event.getForgeRegistry());
Helper.populateObjectHolders(ModEntities.class, BuiltInRegistries.ENTITY_TYPE);
});
event.register(ForgeRegistries.Keys.FEATURES, h -> {
event.register(Registries.FEATURE, h -> {
h.register(new ResourceLocation(NaturesAura.MOD_ID, "aura_bloom"), new LevelGenAuraBloom(ModBlocks.AURA_BLOOM, 60, false));
h.register(new ResourceLocation(NaturesAura.MOD_ID, "aura_cactus"), new LevelGenAuraBloom(ModBlocks.AURA_CACTUS, 60, false));
h.register(new ResourceLocation(NaturesAura.MOD_ID, "warped_aura_mushroom"), new LevelGenAuraBloom(ModBlocks.WARPED_AURA_MUSHROOM, 10, true));
@ -289,26 +292,24 @@ public final class ModRegistry {
h.register(new ResourceLocation(NaturesAura.MOD_ID, "aura_mushroom"), new LevelGenAuraBloom(ModBlocks.AURA_MUSHROOM, 20, false));
h.register(new ResourceLocation(NaturesAura.MOD_ID, "ancient_tree"), new LevelGenAncientTree());
h.register(new ResourceLocation(NaturesAura.MOD_ID, "nether_wart_mushroom"), new LevelGenNetherWartMushroom());
Helper.populateObjectHolders(ModFeatures.class, event.getForgeRegistry());
Helper.populateObjectHolders(ModFeatures.class, BuiltInRegistries.FEATURE);
});
event.register(ForgeRegistries.Keys.RECIPE_TYPES, h -> {
event.register(Registries.RECIPE_TYPE, h -> {
h.register(new ResourceLocation(NaturesAura.MOD_ID, "altar"), ModRecipes.ALTAR_TYPE);
h.register(new ResourceLocation(NaturesAura.MOD_ID, "animal_spawner"), ModRecipes.ANIMAL_SPAWNER_TYPE);
h.register(new ResourceLocation(NaturesAura.MOD_ID, "offering"), ModRecipes.OFFERING_TYPE);
h.register(new ResourceLocation(NaturesAura.MOD_ID, "tree_ritual"), ModRecipes.TREE_RITUAL_TYPE);
});
event.register(ForgeRegistries.Keys.RECIPE_SERIALIZERS, h -> {
event.register(Registries.RECIPE_SERIALIZER, h -> {
h.register(new ResourceLocation(NaturesAura.MOD_ID, "altar"), ModRecipes.ALTAR_SERIALIZER);
h.register(new ResourceLocation(NaturesAura.MOD_ID, "animal_spawner"), ModRecipes.ANIMAL_SPAWNER_SERIALIZER);
h.register(new ResourceLocation(NaturesAura.MOD_ID, "offering"), ModRecipes.OFFERING_SERIALIZER);
h.register(new ResourceLocation(NaturesAura.MOD_ID, "tree_ritual"), ModRecipes.TREE_RITUAL_SERIALIZER);
CraftingHelper.register(new EnabledCondition.Serializer());
});
event.register(BuiltInRegistries.CREATIVE_MODE_TAB.key(), h -> {
event.register(Registries.CREATIVE_MODE_TAB, h -> {
h.register(new ResourceLocation(NaturesAura.MOD_ID, "tab"), CreativeModeTab.builder()
.title(Component.translatable("item_group." + NaturesAura.MOD_ID + ".tab"))
.icon(() -> new ItemStack(ModItems.GOLD_LEAF))
@ -326,12 +327,35 @@ public final class ModRegistry {
.build()
);
});
event.register(NeoForgeRegistries.Keys.ATTACHMENT_TYPES, h -> {
h.register(new ResourceLocation(NaturesAura.MOD_ID, "aura_chunk"), NaturesAuraAPI.AURA_CHUNK_ATTACHMENT);
});
}
@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);
event.registerBlockEntity(ItemHandler.BLOCK, ModBlockEntities.NATURE_ALTAR, (e, c) -> e.items);
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);
}
public static Block createFlowerPot(Block block) {
var props = Block.Properties.of().strength(0F);
Block potted = new BlockFlowerPot(() -> (FlowerPotBlock) Blocks.FLOWER_POT, () -> block, props);
((FlowerPotBlock) Blocks.FLOWER_POT).addPlant(ForgeRegistries.BLOCKS.getKey(block), () -> potted);
((FlowerPotBlock) Blocks.FLOWER_POT).addPlant(BuiltInRegistries.BLOCK.getKey(block), () -> potted);
return potted;
}