some more work~

This commit is contained in:
Ell 2021-12-06 14:38:12 +01:00
parent ba47a8823e
commit 78eaf11948
27 changed files with 657 additions and 750 deletions

View file

@ -1,15 +1,16 @@
package de.ellpeck.naturesaura.api.render; package de.ellpeck.naturesaura.api.render;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
public interface ITrinketItem { public interface ITrinketItem {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
void render(ItemStack stack, Player player, RenderType type, MatrixStack matrices, IRenderTypeBuffer buffer, int packedLight, boolean isHolding); void render(ItemStack stack, Player player, RenderType type, PoseStack matrices, MultiBufferSource buffer, int packedLight, boolean isHolding);
enum RenderType { enum RenderType {
HEAD, BODY HEAD, BODY

View file

@ -1,15 +1,15 @@
package de.ellpeck.naturesaura.api.render; package de.ellpeck.naturesaura.api.render;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.core.BlockPos;
import net.minecraft.util.math.BlockPos; import net.minecraft.world.level.Level;
import net.minecraft.level.Level; import net.minecraft.world.phys.AABB;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
public interface IVisualizable { public interface IVisualizable {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
AxisAlignedBB getVisualizationBounds(Level level, BlockPos pos); AABB getVisualizationBounds(Level level, BlockPos pos);
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
int getVisualizationColor(Level level, BlockPos pos); int getVisualizationColor(Level level, BlockPos pos);

View file

@ -4,39 +4,40 @@ import de.ellpeck.naturesaura.blocks.tiles.BlockEntityImpl;
import de.ellpeck.naturesaura.reg.IModItem; import de.ellpeck.naturesaura.reg.IModItem;
import de.ellpeck.naturesaura.reg.ModRegistry; import de.ellpeck.naturesaura.reg.ModRegistry;
import de.ellpeck.naturesaura.reg.ModTileType; import de.ellpeck.naturesaura.reg.ModTileType;
import net.minecraft.block.*; import net.minecraft.core.BlockPos;
import net.minecraft.entity.LivingEntity; import net.minecraft.core.Direction;
import net.minecraft.entity.player.Player; import net.minecraft.server.level.ServerLevel;
import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.level.IBlockReader;
import net.minecraft.level.ILevel;
import net.minecraft.level.Level;
import net.minecraft.level.server.ServerLevel;
import net.minecraft.loot.LootContext;
import net.minecraft.loot.LootParameters;
import net.minecraft.state.StateContainer;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tags.FluidTags; import net.minecraft.tags.FluidTags;
import net.minecraft.util.Direction; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.BaseEntityBlock; import net.minecraft.world.level.block.BaseEntityBlock;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.entity.BlockEntity; 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.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.function.Supplier;
public class BlockContainerImpl extends BaseEntityBlock implements IModItem { public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
private final String baseName; private final String baseName;
private final ModTileType<? extends BlockEntity> tileType; private final ModTileType<BlockEntity> tileType;
public BlockContainerImpl(String baseName, Supplier<BlockEntity> tileSupplier, Block.Properties properties) { public BlockContainerImpl(String baseName, BlockEntityType.BlockEntitySupplier<BlockEntity> tileSupplier, Block.Properties properties) {
super(properties); super(properties);
this.baseName = baseName; this.baseName = baseName;
@ -46,7 +47,7 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
ModRegistry.add(this.tileType); ModRegistry.add(this.tileType);
if (this.hasWaterlogging()) if (this.hasWaterlogging())
this.setDefaultState(this.stateContainer.getBaseState().with(BlockStateProperties.WATERLOGGED, false)); this.registerDefaultState(this.stateDefinition.any().setValue(BlockStateProperties.WATERLOGGED, false));
} }
protected boolean hasWaterlogging() { protected boolean hasWaterlogging() {
@ -54,37 +55,37 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
} }
@Override @Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) { protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
if (this.hasWaterlogging()) if (this.hasWaterlogging())
builder.add(BlockStateProperties.WATERLOGGED); builder.add(BlockStateProperties.WATERLOGGED);
} }
@Override @Override
public FluidState getFluidState(BlockState state) { public FluidState getFluidState(BlockState state) {
return this.hasWaterlogging() && state.get(BlockStateProperties.WATERLOGGED) ? Fluids.WATER.getStillFluidState(false) : super.getFluidState(state); return this.hasWaterlogging() && state.getValue(BlockStateProperties.WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state);
} }
@Override @Override
public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, ILevel levelIn, BlockPos currentPos, BlockPos facingPos) { public BlockState updateShape(BlockState stateIn, Direction facing, BlockState facingState, LevelAccessor levelIn, BlockPos currentPos, BlockPos facingPos) {
if (this.hasWaterlogging() && stateIn.get(BlockStateProperties.WATERLOGGED)) if (this.hasWaterlogging() && stateIn.getValue(BlockStateProperties.WATERLOGGED))
levelIn.getPendingFluidTicks().scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickRate(levelIn)); levelIn.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(levelIn));
return super.updatePostPlacement(stateIn, facing, facingState, levelIn, currentPos, facingPos); return super.updateShape(stateIn, facing, facingState, levelIn, currentPos, facingPos);
} }
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockItemUseContext context) { public BlockState getStateForPlacement(BlockPlaceContext context) {
if (this.hasWaterlogging()) { if (this.hasWaterlogging()) {
FluidState state = context.getLevel().getFluidState(context.getPos()); FluidState state = context.getLevel().getFluidState(context.getClickedPos());
return this.getDefaultState().with(BlockStateProperties.WATERLOGGED, state.isTagged(FluidTags.WATER) && state.getLevel() == 8); return this.defaultBlockState().setValue(BlockStateProperties.WATERLOGGED, state.is(FluidTags.WATER) && state.getAmount() == 8);
} }
return super.getStateForPlacement(context); return super.getStateForPlacement(context);
} }
@Nullable @org.jetbrains.annotations.Nullable
@Override @Override
public BlockEntity createNewBlockEntity(IBlockReader levelIn) { public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
return this.tileType.type.create(); return this.tileType.type.create(pos, state);
} }
@Override @Override
@ -93,20 +94,15 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
} }
@Override @Override
public BlockRenderType getRenderType(BlockState state) { public RenderShape getRenderShape(BlockState state) {
return BlockRenderType.MODEL; return RenderShape.MODEL;
}
@Override
public void onPlayerDestroy(ILevel levelIn, BlockPos pos, BlockState state) {
super.onPlayerDestroy(levelIn, pos, state);
} }
@Override @Override
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) { public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
List<ItemStack> drops = super.getDrops(state, builder); List<ItemStack> drops = super.getDrops(state, builder);
BlockEntity tile = builder.get(LootParameters.BLOCK_ENTITY); BlockEntity tile = builder.getParameter(LootContextParams.BLOCK_ENTITY);
if (tile instanceof BlockEntityImpl) { if (tile instanceof BlockEntityImpl) {
for (ItemStack stack : drops) { for (ItemStack stack : drops) {
if (stack.getItem() != this.asItem()) if (stack.getItem() != this.asItem())
@ -119,33 +115,28 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
} }
@Override @Override
public void onReplaced(BlockState state, Level levelIn, BlockPos pos, BlockState newState, boolean isMoving) { public void onPlace(BlockState state, Level levelIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.getBlock() != newState.getBlock()) { if (state.getBlock() != newState.getBlock()) {
BlockEntity tile = levelIn.getBlockEntity(pos); BlockEntity tile = levelIn.getBlockEntity(pos);
if (tile instanceof BlockEntityImpl) if (tile instanceof BlockEntityImpl)
((BlockEntityImpl) tile).dropInventory(); ((BlockEntityImpl) tile).dropInventory();
} }
super.onReplaced(state, levelIn, pos, newState, isMoving); super.onPlace(state, levelIn, pos, newState, isMoving);
} }
@Override @Override
public void harvestBlock(Level levelIn, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack) { public void playerDestroy(Level levelIn, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack) {
super.harvestBlock(levelIn, player, pos, state, te, stack); super.playerDestroy(levelIn, player, pos, state, te, stack);
levelIn.setBlockState(pos, Blocks.AIR.getDefaultState()); levelIn.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState());
} }
@Override @Override
public void onBlockPlacedBy(Level levelIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { public void setPlacedBy(Level levelIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
BlockEntity tile = levelIn.getBlockEntity(pos); BlockEntity tile = levelIn.getBlockEntity(pos);
if (tile instanceof BlockEntityImpl) if (tile instanceof BlockEntityImpl)
((BlockEntityImpl) tile).loadDataOnPlace(stack); ((BlockEntityImpl) tile).loadDataOnPlace(stack);
} }
@Override
public void onBlockAdded(BlockState state, Level levelIn, BlockPos pos, BlockState oldState, boolean isMoving) {
this.updateRedstoneState(levelIn, pos);
}
@Override @Override
public void neighborChanged(BlockState state, Level levelIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) { public void neighborChanged(BlockState state, Level levelIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) {
this.updateRedstoneState(levelIn, pos); this.updateRedstoneState(levelIn, pos);
@ -154,11 +145,10 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
private void updateRedstoneState(Level level, BlockPos pos) { private void updateRedstoneState(Level level, BlockPos pos) {
if (!level.isClientSide) { if (!level.isClientSide) {
BlockEntity tile = level.getBlockEntity(pos); BlockEntity tile = level.getBlockEntity(pos);
if (tile instanceof BlockEntityImpl) { if (tile instanceof BlockEntityImpl impl) {
BlockEntityImpl impl = (BlockEntityImpl) tile; int newPower = level.getBestNeighborSignal(pos);
int newPower = level.getRedstonePowerFromNeighbors(pos);
if (impl.redstonePower != newPower) if (impl.redstonePower != newPower)
level.getPendingBlockTicks().scheduleTick(pos, this, 4); level.scheduleTick(pos, this, 4);
} }
} }
} }
@ -167,9 +157,8 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
public void tick(BlockState state, ServerLevel levelIn, BlockPos pos, Random random) { public void tick(BlockState state, ServerLevel levelIn, BlockPos pos, Random random) {
if (!levelIn.isClientSide) { if (!levelIn.isClientSide) {
BlockEntity tile = levelIn.getBlockEntity(pos); BlockEntity tile = levelIn.getBlockEntity(pos);
if (tile instanceof BlockEntityImpl) { if (tile instanceof BlockEntityImpl impl) {
BlockEntityImpl impl = (BlockEntityImpl) tile; int newPower = levelIn.getBestNeighborSignal(pos);
int newPower = levelIn.getRedstonePowerFromNeighbors(pos);
if (impl.redstonePower != newPower) if (impl.redstonePower != newPower)
impl.onRedstonePowerChange(newPower); impl.onRedstonePowerChange(newPower);
} }

View file

@ -2,49 +2,45 @@ package de.ellpeck.naturesaura.blocks;
import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.misc.ILevelData; import de.ellpeck.naturesaura.api.misc.ILevelData;
import de.ellpeck.naturesaura.blocks.tiles.ModTileEntities;
import de.ellpeck.naturesaura.blocks.tiles.BlockEntityEnderCrate; import de.ellpeck.naturesaura.blocks.tiles.BlockEntityEnderCrate;
import de.ellpeck.naturesaura.blocks.tiles.ModTileEntities;
import de.ellpeck.naturesaura.blocks.tiles.render.RenderEnderCrate; import de.ellpeck.naturesaura.blocks.tiles.render.RenderEnderCrate;
import de.ellpeck.naturesaura.data.BlockStateGenerator; import de.ellpeck.naturesaura.data.BlockStateGenerator;
import de.ellpeck.naturesaura.items.ModItems; import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.reg.ICustomBlockState; import de.ellpeck.naturesaura.reg.ICustomBlockState;
import de.ellpeck.naturesaura.reg.ITESRProvider; import de.ellpeck.naturesaura.reg.ITESRProvider;
import net.minecraft.block.AnvilBlock; import net.minecraft.ChatFormatting;
import net.minecraft.block.BlockState; import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
import net.minecraft.block.SoundType; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.block.material.Material; import net.minecraft.client.resources.language.I18n;
import net.minecraft.client.renderer.tileentity.BlockEntityRenderer; import net.minecraft.core.BlockPos;
import net.minecraft.client.renderer.tileentity.BlockEntityRendererDispatcher; import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.client.resources.I18n; import net.minecraft.network.chat.Component;
import net.minecraft.client.util.ITooltipFlag; import net.minecraft.network.chat.TextComponent;
import net.minecraft.entity.player.Player; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.entity.player.ServerPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.tileentity.BlockEntity;
import net.minecraft.tileentity.BlockEntityType;
import net.minecraft.util.InteractionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.Tuple; import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos; import net.minecraft.world.InteractionHand;
import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.world.InteractionResult;
import net.minecraft.util.text.ITextComponent; import net.minecraft.world.entity.player.Player;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.world.item.ItemStack;
import net.minecraft.util.text.TextFormatting; import net.minecraft.world.item.Items;
import net.minecraft.level.IBlockReader; import net.minecraft.world.item.TooltipFlag;
import net.minecraft.level.Level; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.SoundType;
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.minecraft.world.level.material.Material;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.AnvilUpdateEvent; import net.minecraftforge.event.AnvilUpdateEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.network.NetworkHooks;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.function.Function; import java.util.function.Function;
@ -52,11 +48,8 @@ import java.util.function.Supplier;
public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider<BlockEntityEnderCrate>, ICustomBlockState { public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider<BlockEntityEnderCrate>, ICustomBlockState {
// This is terrible but I can't see a better solution right now so oh well
private static final ThreadLocal<WeakReference<Level>> CACHED_WORLD = new ThreadLocal<>();
public BlockEnderCrate() { public BlockEnderCrate() {
super("ender_crate", BlockEntityEnderCrate::new, Properties.create(Material.ROCK).hardnessAndResistance(5F).setLightLevel(s -> 7).sound(SoundType.STONE)); super("ender_crate", BlockEntityEnderCrate::new, Properties.of(Material.STONE).strength(5F).lightLevel(s -> 7).sound(SoundType.STONE));
MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(this);
} }
@ -68,32 +61,22 @@ public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public static void addEnderNameInfo(ItemStack stack, List<ITextComponent> tooltip) { public static void addEnderNameInfo(ItemStack stack, List<Component> tooltip) {
String name = getEnderName(stack); String name = getEnderName(stack);
if (name != null && !name.isEmpty()) if (name != null && !name.isEmpty()) {
tooltip.add(new StringTextComponent(TextFormatting.DARK_PURPLE + I18n.format("info." + NaturesAura.MOD_ID + ".ender_name", tooltip.add(new TextComponent(ChatFormatting.DARK_PURPLE + I18n.get("info." + NaturesAura.MOD_ID + ".ender_name", ChatFormatting.ITALIC + name + ChatFormatting.RESET)));
TextFormatting.ITALIC + name + TextFormatting.RESET))); } else {
else tooltip.add(new TextComponent(ChatFormatting.DARK_PURPLE + I18n.get("info." + NaturesAura.MOD_ID + ".ender_name.missing")));
tooltip.add(new StringTextComponent(TextFormatting.DARK_PURPLE + I18n.format("info." + NaturesAura.MOD_ID + ".ender_name.missing")));
}
@SubscribeEvent
public void onRightClick(PlayerInteractEvent.RightClickBlock event) {
Level level = event.getLevel();
BlockPos pos = event.getPos();
BlockState state = level.getBlockState(pos);
if (state.getBlock() instanceof AnvilBlock) {
CACHED_WORLD.set(new WeakReference<>(level));
} }
} }
@SubscribeEvent @SubscribeEvent
public void onAnvilUpdate(AnvilUpdateEvent event) { public void onAnvilUpdate(AnvilUpdateEvent event) {
WeakReference<Level> level = CACHED_WORLD.get(); var player = event.getPlayer();
if (level == null || level.get() == null) if (player == null)
return; return;
ItemStack stack = event.getLeft(); ItemStack stack = event.getLeft();
if (stack.getItem() != Item.getItemFromBlock(this) && stack.getItem() != ModItems.ENDER_ACCESS) if (stack.getItem() != this.asItem() && stack.getItem() != ModItems.ENDER_ACCESS)
return; return;
ItemStack second = event.getRight(); ItemStack second = event.getRight();
if (second.getItem() != Items.ENDER_EYE || second.getCount() < stack.getCount()) if (second.getItem() != Items.ENDER_EYE || second.getCount() < stack.getCount())
@ -101,7 +84,7 @@ public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider
String name = event.getName(); String name = event.getName();
if (name == null || name.isEmpty()) if (name == null || name.isEmpty())
return; return;
if (ILevelData.getOverworldData(level.get()).isEnderStorageLocked(name)) if (ILevelData.getOverworldData(player.level).isEnderStorageLocked(name))
return; return;
ItemStack output = stack.copy(); ItemStack output = stack.copy();
output.getOrCreateTag().putString(NaturesAura.MOD_ID + ":ender_name", name); output.getOrCreateTag().putString(NaturesAura.MOD_ID + ":ender_name", name);
@ -111,15 +94,12 @@ public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider
} }
@Override @Override
public InteractionResult onBlockActivated(BlockState state, Level levelIn, BlockPos pos, Player player, Hand handIn, BlockRayTraceResult hit) { public InteractionResult use(BlockState state, Level levelIn, BlockPos pos, Player player, InteractionHand handIn, BlockHitResult hit) {
if (!levelIn.isClientSide) { if (!levelIn.isClientSide) {
BlockEntity tile = levelIn.getBlockEntity(pos); BlockEntity tile = levelIn.getBlockEntity(pos);
if (tile instanceof BlockEntityEnderCrate) { if (tile instanceof BlockEntityEnderCrate crate && crate.canOpen()) {
BlockEntityEnderCrate crate = (BlockEntityEnderCrate) tile; crate.drainAura(2500);
if (crate.canOpen()) { NetworkHooks.openGui((ServerPlayer) player, crate, pos);
crate.drainAura(2500);
NetworkHooks.openGui((ServerPlayer) player, crate, pos);
}
} }
} }
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
@ -127,7 +107,7 @@ public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void addInformation(ItemStack stack, @Nullable IBlockReader levelIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) { public void appendHoverText(ItemStack stack, @Nullable BlockGetter levelIn, List<Component> tooltip, TooltipFlag flagIn) {
addEnderNameInfo(stack, tooltip); addEnderNameInfo(stack, tooltip);
} }
@ -148,7 +128,7 @@ public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider
} }
@Override @Override
public Tuple<BlockEntityType<BlockEntityEnderCrate>, Supplier<Function<? super BlockEntityRendererDispatcher, ? extends BlockEntityRenderer<? super BlockEntityEnderCrate>>>> getTESR() { public Tuple<BlockEntityType<BlockEntityEnderCrate>, Supplier<Function<? super BlockEntityRenderDispatcher, ? extends BlockEntityRenderer<? super BlockEntityEnderCrate>>>> getTESR() {
return new Tuple<>(ModTileEntities.ENDER_CRATE, () -> RenderEnderCrate::new); return new Tuple<>(ModTileEntities.ENDER_CRATE, () -> RenderEnderCrate::new);
} }

View file

@ -1,15 +1,16 @@
package de.ellpeck.naturesaura.blocks.tiles; package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import net.minecraft.tileentity.ITickableBlockEntity; import net.minecraft.core.BlockPos;
import net.minecraft.util.math.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.level.block.state.BlockState;
public class BlockEntityAuraDetector extends BlockEntityImpl implements ITickableBlockEntity { public class BlockEntityAuraDetector extends BlockEntityImpl implements ITickableBlockEntity {
public int redstonePower; public int redstonePower;
public BlockEntityAuraDetector() { public BlockEntityAuraDetector(BlockPos pos, BlockState state) {
super(ModTileEntities.AURA_DETECTOR); super(ModTileEntities.AURA_DETECTOR, pos, state);
} }
@Override @Override
@ -19,7 +20,7 @@ public class BlockEntityAuraDetector extends BlockEntityImpl implements ITickabl
int power = Mth.clamp(Mth.ceil(totalAmount / (IAuraChunk.DEFAULT_AURA * 2F) * 15F), 0, 15); int power = Mth.clamp(Mth.ceil(totalAmount / (IAuraChunk.DEFAULT_AURA * 2F) * 15F), 0, 15);
if (this.redstonePower != power) { if (this.redstonePower != power) {
this.redstonePower = power; this.redstonePower = power;
this.level.updateComparatorOutputLevel(this.worldPosition, this.getBlockState().getBlock()); this.level.updateNeighbourForOutputSignal(this.worldPosition, this.getBlockState().getBlock());
} }
} }
} }

View file

@ -7,11 +7,11 @@ import de.ellpeck.naturesaura.items.ItemAuraBottle;
import de.ellpeck.naturesaura.items.ModItems; import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.packet.PacketHandler; import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles; import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.block.BlockState; import net.minecraft.core.BlockPos;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.world.item.ItemStack;
import net.minecraft.tileentity.ITickableBlockEntity; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.IItemHandlerModifiable;
import java.util.Map; import java.util.Map;
@ -30,8 +30,8 @@ public class BlockEntityAuraTimer extends BlockEntityImpl implements ITickableBl
}; };
private int timer; private int timer;
public BlockEntityAuraTimer() { public BlockEntityAuraTimer(BlockPos pos, BlockState state) {
super(ModTileEntities.AURA_TIMER); super(ModTileEntities.AURA_TIMER, pos, state);
} }
@Override @Override
@ -57,10 +57,10 @@ public class BlockEntityAuraTimer extends BlockEntityImpl implements ITickableBl
if (this.level.getGameTime() % 8 == 0) { if (this.level.getGameTime() % 8 == 0) {
int color = ItemAuraBottle.getType(this.itemHandler.getStackInSlot(0)).getColor(); int color = ItemAuraBottle.getType(this.itemHandler.getStackInSlot(0)).getColor();
NaturesAuraAPI.instance().spawnMagicParticle( NaturesAuraAPI.instance().spawnMagicParticle(
this.worldPosition.getX() + 1 / 16F + this.level.rand.nextFloat() * 14 / 16F, this.worldPosition.getX() + 1 / 16F + this.level.random.nextFloat() * 14 / 16F,
this.worldPosition.getY() + 1 / 16F + this.level.rand.nextFloat() * 14 / 16F, this.worldPosition.getY() + 1 / 16F + this.level.random.nextFloat() * 14 / 16F,
this.worldPosition.getZ() + 1 / 16F + this.level.rand.nextFloat() * 14 / 16F, this.worldPosition.getZ() + 1 / 16F + this.level.random.nextFloat() * 14 / 16F,
0, 0, 0, color, 1, 80 + this.level.rand.nextInt(50), 0, false, true); 0, 0, 0, color, 1, 80 + this.level.random.nextInt(50), 0, false, true);
} }
return; return;
} }
@ -70,8 +70,8 @@ public class BlockEntityAuraTimer extends BlockEntityImpl implements ITickableBl
this.timer = 0; this.timer = 0;
BlockState state = this.getBlockState(); BlockState state = this.getBlockState();
this.level.setBlockState(this.worldPosition, state.with(BlockStateProperties.POWERED, true), 1); this.level.setBlock(this.worldPosition, state.setValue(BlockStateProperties.POWERED, true), 1);
this.level.getPendingBlockTicks().scheduleTick(this.worldPosition, state.getBlock(), 4); this.level.scheduleTick(this.worldPosition, state.getBlock(), 4);
int color = ItemAuraBottle.getType(this.itemHandler.getStackInSlot(0)).getColor(); int color = ItemAuraBottle.getType(this.itemHandler.getStackInSlot(0)).getColor();
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticles(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), PacketParticles.Type.TIMER_RESET, color)); PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticles(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), PacketParticles.Type.TIMER_RESET, color));

View file

@ -0,0 +1,112 @@
package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.blocks.BlockAutoCrafter;
import de.ellpeck.naturesaura.blocks.multi.Multiblocks;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.EntitySelector;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.CraftingContainer;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
public class BlockEntityAutoCrafter extends BlockEntityImpl implements ITickableBlockEntity {
public final CraftingContainer crafting = new CraftingContainer(new AbstractContainerMenu(null, 0) {
@Override
public boolean stillValid(Player playerIn) {
return false;
}
}, 3, 3);
public BlockEntityAutoCrafter(BlockPos pos, BlockState state) {
super(ModTileEntities.AUTO_CRAFTER, pos, state);
}
@Override
public void tick() {
if (!this.level.isClientSide) {
if (this.level.getGameTime() % 60 != 0)
return;
if (!Multiblocks.AUTO_CRAFTER.isComplete(this.level, this.worldPosition))
return;
this.crafting.clearContent();
var state = this.level.getBlockState(this.worldPosition);
Direction facing = state.getValue(BlockAutoCrafter.FACING);
var middlePos = this.worldPosition.above();
var topPos = middlePos.relative(facing, 2);
var bottomPos = middlePos.relative(facing.getOpposite(), 2);
var poses = new BlockPos[]{
topPos.relative(facing.getCounterClockWise(), 2),
topPos,
topPos.relative(facing.getClockWise(), 2),
middlePos.relative(facing.getCounterClockWise(), 2),
middlePos,
middlePos.relative(facing.getClockWise(), 2),
bottomPos.relative(facing.getCounterClockWise(), 2),
bottomPos,
bottomPos.relative(facing.getClockWise(), 2)
};
var items = new ItemEntity[9];
for (var i = 0; i < poses.length; i++) {
var entities = this.level.getEntitiesOfClass(
ItemEntity.class, new AABB(poses[i]).inflate(0.25), EntitySelector.ENTITY_STILL_ALIVE);
if (entities.size() > 1)
return;
if (entities.isEmpty())
continue;
var entity = entities.get(0);
if (entity.hasPickUpDelay())
return;
var stack = entity.getItem();
if (stack.isEmpty())
return;
items[i] = entity;
this.crafting.setItem(i, stack.copy());
}
var recipe = this.level.getRecipeManager().getRecipeFor(RecipeType.CRAFTING, this.crafting, this.level).orElse(null);
if (recipe == null)
return;
var result = recipe.assemble(this.crafting);
if (result.isEmpty())
return;
var resultItem = new ItemEntity(this.level,
this.worldPosition.getX() + 0.5F, this.worldPosition.getY() - 0.35F, this.worldPosition.getZ() + 0.5F, result.copy());
resultItem.setDeltaMovement(0, 0, 0);
this.level.addFreshEntity(resultItem);
var remainingItems = recipe.getRemainingItems(this.crafting);
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item == null)
continue;
var stack = item.getItem();
if (stack.getCount() <= 1)
item.discard();
else {
stack.shrink(1);
item.setItem(stack);
}
var remain = remainingItems.get(i);
if (!remain.isEmpty()) {
var remItem = new ItemEntity(this.level, item.getX(), item.getY(), item.getZ(), remain.copy());
remItem.setDeltaMovement(0, 0, 0);
this.level.addFreshEntity(remItem);
}
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32,
new PacketParticles((float) item.getX(), (float) item.getY(), (float) item.getZ(), PacketParticles.Type.ANIMAL_SPAWNER));
}
}
}
}

View file

@ -3,15 +3,15 @@ package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.packet.PacketHandler; import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles; import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.item.ItemStack; import net.minecraft.core.BlockPos;
import net.minecraft.item.crafting.IRecipe; import net.minecraft.core.Direction;
import net.minecraft.item.crafting.Ingredient; import net.minecraft.world.inventory.ContainerData;
import net.minecraft.tileentity.BlastFurnaceBlockEntity; import net.minecraft.world.item.ItemStack;
import net.minecraft.tileentity.ITickableBlockEntity; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.tileentity.BlockEntity; import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.util.Direction; import net.minecraft.world.level.block.entity.BlastFurnaceBlockEntity;
import net.minecraft.util.IIntArray; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.IItemHandlerModifiable;
@ -21,8 +21,8 @@ import java.util.List;
public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements ITickableBlockEntity { public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements ITickableBlockEntity {
public BlockEntityBlastFurnaceBooster() { public BlockEntityBlastFurnaceBooster(BlockPos pos, BlockState state) {
super(ModTileEntities.BLAST_FURNACE_BOOSTER); super(ModTileEntities.BLAST_FURNACE_BOOSTER, pos, state);
} }
@Override @Override
@ -30,34 +30,33 @@ public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements I
if (this.level.isClientSide) if (this.level.isClientSide)
return; return;
BlockEntity below = this.level.getBlockEntity(this.worldPosition.down()); BlockEntity below = this.level.getBlockEntity(this.worldPosition.below());
if (!(below instanceof BlastFurnaceBlockEntity)) if (!(below instanceof BlastFurnaceBlockEntity tile))
return; return;
BlastFurnaceBlockEntity tile = (BlastFurnaceBlockEntity) below; Recipe<?> recipe = this.level.getRecipeManager().getRecipeFor(BlockEntityFurnaceHeater.getRecipeType(tile), tile, this.level).orElse(null);
IRecipe<?> recipe = this.level.getRecipeManager().getRecipe(BlockEntityFurnaceHeater.getRecipeType(tile), tile, this.level).orElse(null);
if (recipe == null) if (recipe == null)
return; return;
if (!this.isApplicable(recipe.getIngredients())) if (!this.isApplicable(recipe.getIngredients()))
return; return;
IIntArray data = BlockEntityFurnaceHeater.getFurnaceData(tile); ContainerData data = BlockEntityFurnaceHeater.getFurnaceData(tile);
int doneDiff = data.get(3) - data.get(2); int doneDiff = data.get(3) - data.get(2);
if (doneDiff > 1) if (doneDiff > 1)
return; return;
if (this.level.rand.nextFloat() > 0.45F) { if (this.level.random.nextFloat() > 0.45F) {
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, PacketHandler.sendToAllAround(this.level, this.worldPosition, 32,
new PacketParticles(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), PacketParticles.Type.BLAST_FURNACE_BOOSTER, 0)); new PacketParticles(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), PacketParticles.Type.BLAST_FURNACE_BOOSTER, 0));
return; return;
} }
ItemStack output = tile.getStackInSlot(2); ItemStack output = tile.getItem(2);
if (output.getCount() >= output.getMaxStackSize()) if (output.getCount() >= output.getMaxStackSize())
return; return;
if (output.isEmpty()) { if (output.isEmpty()) {
ItemStack result = recipe.getRecipeOutput(); ItemStack result = recipe.getResultItem();
tile.setInventorySlotContents(2, result.copy()); tile.setItem(2, result.copy());
} else { } else {
output.grow(1); output.grow(1);
} }
@ -71,7 +70,7 @@ public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements I
private boolean isApplicable(List<Ingredient> ingredients) { private boolean isApplicable(List<Ingredient> ingredients) {
for (Ingredient ing : ingredients) { for (Ingredient ing : ingredients) {
for (ItemStack stack : ing.getMatchingStacks()) { for (ItemStack stack : ing.getItems()) {
if (stack.getItem().getTags().stream().anyMatch(t -> t.getPath().startsWith("ores/"))) if (stack.getItem().getTags().stream().anyMatch(t -> t.getPath().startsWith("ores/")))
return true; return true;
} }
@ -81,7 +80,7 @@ public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements I
@Override @Override
public IItemHandlerModifiable getItemHandler() { public IItemHandlerModifiable getItemHandler() {
BlockEntity below = this.level.getBlockEntity(this.worldPosition.down()); BlockEntity below = this.level.getBlockEntity(this.worldPosition.below());
if (!(below instanceof BlastFurnaceBlockEntity)) if (!(below instanceof BlastFurnaceBlockEntity))
return null; return null;
IItemHandler handler = below.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, Direction.UP).orElse(null); IItemHandler handler = below.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, Direction.UP).orElse(null);

View file

@ -1,18 +1,16 @@
package de.ellpeck.naturesaura.blocks.tiles; package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.packet.PacketHandler; import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles; import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.block.BlockState; import net.minecraft.core.BlockPos;
import net.minecraft.block.Blocks; import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NbtUtils;
import net.minecraft.tileentity.ITickableBlockEntity; import net.minecraft.sounds.SoundEvents;
import net.minecraft.util.Direction; import net.minecraft.sounds.SoundSource;
import net.minecraft.util.SoundCategory; import net.minecraft.world.level.block.Blocks;
import net.minecraft.util.SoundEvents; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.util.math.BlockPos;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
@ -24,8 +22,8 @@ public class BlockEntityChorusGenerator extends BlockEntityImpl implements ITick
private final Deque<BlockPos> currentlyBreaking = new ArrayDeque<>(); private final Deque<BlockPos> currentlyBreaking = new ArrayDeque<>();
private int auraPerBlock; private int auraPerBlock;
public BlockEntityChorusGenerator() { public BlockEntityChorusGenerator(BlockPos pos, BlockState state) {
super(ModTileEntities.CHORUS_GENERATOR); super(ModTileEntities.CHORUS_GENERATOR, pos, state);
} }
@Override @Override
@ -45,7 +43,7 @@ public class BlockEntityChorusGenerator extends BlockEntityImpl implements ITick
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticles(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), PacketParticles.Type.CHORUS_GENERATOR, pos.getX(), pos.getY(), pos.getZ())); PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticles(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), PacketParticles.Type.CHORUS_GENERATOR, pos.getX(), pos.getY(), pos.getZ()));
this.level.removeBlock(pos, false); this.level.removeBlock(pos, false);
this.level.playSound(null, this.worldPosition.getX() + 0.5, this.worldPosition.getY() + 0.5, this.worldPosition.getZ() + 0.5, this.level.playSound(null, this.worldPosition.getX() + 0.5, this.worldPosition.getY() + 0.5, this.worldPosition.getZ() + 0.5,
SoundEvents.ITEM_CHORUS_FRUIT_TELEPORT, SoundCategory.BLOCKS, 0.5F, 1F); SoundEvents.CHORUS_FRUIT_TELEPORT, SoundSource.BLOCKS, 0.5F, 1F);
this.generateAura(this.auraPerBlock); this.generateAura(this.auraPerBlock);
} }
@ -57,8 +55,8 @@ public class BlockEntityChorusGenerator extends BlockEntityImpl implements ITick
for (int x = -range; x <= range; x++) { for (int x = -range; x <= range; x++) {
for (int y = -range; y <= range; y++) { for (int y = -range; y <= range; y++) {
for (int z = -range; z <= range; z++) { for (int z = -range; z <= range; z++) {
BlockPos offset = this.worldPosition.add(x, y, z); BlockPos offset = this.worldPosition.offset(x, y, z);
BlockState below = this.level.getBlockState(offset.down()); BlockState below = this.level.getBlockState(offset.below());
if (below.getBlock() != Blocks.END_STONE) if (below.getBlock() != Blocks.END_STONE)
continue; continue;
BlockState state = this.level.getBlockState(offset); BlockState state = this.level.getBlockState(offset);
@ -87,7 +85,7 @@ public class BlockEntityChorusGenerator extends BlockEntityImpl implements ITick
for (Direction dir : Direction.values()) { for (Direction dir : Direction.values()) {
if (dir == Direction.DOWN) if (dir == Direction.DOWN)
continue; continue;
BlockPos offset = pos.offset(dir); BlockPos offset = pos.relative(dir);
if (blocks.contains(offset)) if (blocks.contains(offset))
continue; continue;
BlockState state = this.level.getBlockState(offset); BlockState state = this.level.getBlockState(offset);
@ -102,9 +100,9 @@ public class BlockEntityChorusGenerator extends BlockEntityImpl implements ITick
public void writeNBT(CompoundTag compound, SaveType type) { public void writeNBT(CompoundTag compound, SaveType type) {
super.writeNBT(compound, type); super.writeNBT(compound, type);
if (type == SaveType.TILE) { if (type == SaveType.TILE) {
ListNBT list = new ListNBT(); ListTag list = new ListTag();
for (BlockPos pos : this.currentlyBreaking) for (BlockPos pos : this.currentlyBreaking)
list.add(NBTUtil.writeBlockPos(pos)); list.add(NbtUtils.writeBlockPos(pos));
compound.put("breaking", list); compound.put("breaking", list);
compound.putInt("aura", this.auraPerBlock); compound.putInt("aura", this.auraPerBlock);
} }
@ -115,9 +113,9 @@ public class BlockEntityChorusGenerator extends BlockEntityImpl implements ITick
super.readNBT(compound, type); super.readNBT(compound, type);
if (type == SaveType.TILE) { if (type == SaveType.TILE) {
this.currentlyBreaking.clear(); this.currentlyBreaking.clear();
ListNBT list = compound.getList("breaking", 10); ListTag list = compound.getList("breaking", 10);
for (int i = 0; i < list.size(); i++) for (int i = 0; i < list.size(); i++)
this.currentlyBreaking.add(NBTUtil.readBlockPos(list.getCompound(i))); this.currentlyBreaking.add(NbtUtils.readBlockPos(list.getCompound(i)));
this.auraPerBlock = compound.getInt("aura"); this.auraPerBlock = compound.getInt("aura");
} }
} }

View file

@ -2,12 +2,12 @@ package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.ModConfig; import de.ellpeck.naturesaura.ModConfig;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.tileentity.ITickableBlockEntity; import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.Mth;
import net.minecraft.util.math.ChunkPos; import net.minecraft.world.level.ChunkPos;
import net.minecraft.util.math.Mth; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.level.server.ServerLevel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -19,13 +19,13 @@ public class BlockEntityChunkLoader extends BlockEntityImpl implements ITickable
private final List<ChunkPos> forcedChunks = new ArrayList<>(); private final List<ChunkPos> forcedChunks = new ArrayList<>();
private boolean firstTick = true; private boolean firstTick = true;
public BlockEntityChunkLoader() { public BlockEntityChunkLoader(BlockPos pos, BlockState state) {
super(ModTileEntities.CHUNK_LOADER); super(ModTileEntities.CHUNK_LOADER, pos, state);
} }
@Override @Override
public void remove() { public void setRemoved() {
super.remove(); super.setRemoved();
this.loadChunks(true); this.loadChunks(true);
} }
@ -55,23 +55,23 @@ public class BlockEntityChunkLoader extends BlockEntityImpl implements ITickable
for (int z = (this.worldPosition.getZ() - range) >> 4; z <= (this.worldPosition.getZ() + range) >> 4; z++) { for (int z = (this.worldPosition.getZ() - range) >> 4; z <= (this.worldPosition.getZ() + range) >> 4; z++) {
ChunkPos pos = new ChunkPos(x, z); ChunkPos pos = new ChunkPos(x, z);
// Only force chunks that we're already forcing or that nobody else is forcing // Only force chunks that we're already forcing or that nobody else is forcing
if (this.forcedChunks.contains(pos) || !level.getForcedChunks().contains(pos.asLong())) if (this.forcedChunks.contains(pos) || !level.getForcedChunks().contains(pos.toLong()))
shouldBeForced.add(pos); shouldBeForced.add(pos);
} }
} }
} }
} }
// Unforce all of the chunks that shouldn't be forced anymore // Unforce all the chunks that shouldn't be forced anymore
for (ChunkPos pos : this.forcedChunks) { for (ChunkPos pos : this.forcedChunks) {
if (!shouldBeForced.contains(pos)) if (!shouldBeForced.contains(pos))
level.forceChunk(pos.x, pos.z, false); level.setChunkForced(pos.x, pos.z, false);
} }
this.forcedChunks.clear(); this.forcedChunks.clear();
// Force all chunks that should be forced // Force all chunks that should be forced
for (ChunkPos pos : shouldBeForced) { for (ChunkPos pos : shouldBeForced) {
level.forceChunk(pos.x, pos.z, true); level.setChunkForced(pos.x, pos.z, true);
this.forcedChunks.add(pos); this.forcedChunks.add(pos);
} }
} }
@ -100,7 +100,7 @@ public class BlockEntityChunkLoader extends BlockEntityImpl implements ITickable
public void writeNBT(CompoundTag compound, SaveType type) { public void writeNBT(CompoundTag compound, SaveType type) {
super.writeNBT(compound, type); super.writeNBT(compound, type);
if (type == SaveType.TILE) if (type == SaveType.TILE)
compound.putLongArray("forced_chunks", this.forcedChunks.stream().map(ChunkPos::asLong).collect(Collectors.toList())); compound.putLongArray("forced_chunks", this.forcedChunks.stream().map(ChunkPos::toLong).collect(Collectors.toList()));
} }
@Override @Override

View file

@ -0,0 +1,130 @@
package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.blocks.BlockFurnaceHeater;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticleStream;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.Mth;
import net.minecraft.world.inventory.ContainerData;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.AbstractCookingRecipe;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.block.AbstractFurnaceBlock;
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
import net.minecraft.world.level.block.entity.BlastFurnaceBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.SmokerBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
import java.lang.reflect.Field;
public class BlockEntityFurnaceHeater extends BlockEntityImpl implements ITickableBlockEntity {
private static final Field FURNACE_DATA_FIELD = ObfuscationReflectionHelper.findField(AbstractFurnaceBlockEntity.class, "dataAccess");
public boolean isActive;
public BlockEntityFurnaceHeater(BlockPos pos, BlockState state) {
super(ModTileEntities.FURNACE_HEATER, pos, state);
}
public static ContainerData getFurnaceData(AbstractFurnaceBlockEntity tile) {
try {
return (ContainerData) FURNACE_DATA_FIELD.get(tile);
} catch (IllegalAccessException e) {
NaturesAura.LOGGER.fatal("Couldn't reflect furnace field", e);
return null;
}
}
public static RecipeType<? extends AbstractCookingRecipe> getRecipeType(AbstractFurnaceBlockEntity furnace) {
if (furnace instanceof BlastFurnaceBlockEntity) {
return RecipeType.BLASTING;
} else if (furnace instanceof SmokerBlockEntity) {
return RecipeType.SMOKING;
} else {
return RecipeType.SMELTING;
}
}
@Override
public void tick() {
if (!this.level.isClientSide && this.level.getGameTime() % 5 == 0) {
boolean did = false;
Direction facing = this.level.getBlockState(this.worldPosition).getValue(BlockFurnaceHeater.FACING);
BlockPos tilePos = this.worldPosition.relative(facing.getOpposite());
BlockEntity tile = this.level.getBlockEntity(tilePos);
if (tile instanceof AbstractFurnaceBlockEntity furnace && this.isReady(furnace)) {
ContainerData data = getFurnaceData(furnace);
int burnTime = data.get(0);
if (burnTime <= 0)
this.level.setBlockAndUpdate(tilePos, this.level.getBlockState(tilePos).setValue(AbstractFurnaceBlock.LIT, true));
data.set(0, 200);
//if set higher than 199, it'll never finish because the furnace does ++ and then ==
data.set(2, Math.min(data.get(3) - 1, data.get(2) + 5));
BlockPos spot = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 20, this.worldPosition);
IAuraChunk chunk = IAuraChunk.getAuraChunk(this.level, spot);
chunk.drainAura(spot, Mth.ceil((200 - burnTime) * 16.6F));
did = true;
if (this.level.getGameTime() % 15 == 0) {
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticleStream(
this.worldPosition.getX() + (float) this.level.random.nextGaussian() * 5F,
this.worldPosition.getY() + 1 + this.level.random.nextFloat() * 5F,
this.worldPosition.getZ() + (float) this.level.random.nextGaussian() * 5F,
tilePos.getX() + this.level.random.nextFloat(),
tilePos.getY() + this.level.random.nextFloat(),
tilePos.getZ() + this.level.random.nextFloat(),
this.level.random.nextFloat() * 0.07F + 0.07F, IAuraType.forLevel(this.level).getColor(), this.level.random.nextFloat() + 0.5F
));
}
}
if (did != this.isActive) {
this.isActive = did;
this.sendToClients();
}
}
}
private boolean isReady(AbstractFurnaceBlockEntity furnace) {
if (!furnace.getItem(1).isEmpty())
return false;
ItemStack input = furnace.getItem(0);
if (!input.isEmpty()) {
AbstractCookingRecipe recipe = this.level.getRecipeManager().getRecipeFor(getRecipeType(furnace), furnace, this.level).orElse(null);
if (recipe == null)
return false;
ItemStack output = recipe.getResultItem();
ItemStack currOutput = furnace.getItem(2);
return currOutput.isEmpty() || Helper.areItemsEqual(currOutput, output, true) && currOutput.getCount() + output.getCount() <= output.getMaxStackSize();
} else
return false;
}
@Override
public void writeNBT(CompoundTag compound, SaveType type) {
super.writeNBT(compound, type);
if (type == SaveType.SYNC)
compound.putBoolean("active", this.isActive);
}
@Override
public void readNBT(CompoundTag compound, SaveType type) {
super.readNBT(compound, type);
if (type == SaveType.SYNC)
this.isActive = compound.getBoolean("active");
}
}

View file

@ -1,6 +1,6 @@
package de.ellpeck.naturesaura.blocks.tiles; package de.ellpeck.naturesaura.blocks.tiles;
import net.minecraft.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -23,7 +23,7 @@ public class ItemStackHandlerNA extends ItemStackHandler {
@Override @Override
protected void onContentsChanged(int slot) { protected void onContentsChanged(int slot) {
if (this.tile != null) { if (this.tile != null) {
this.tile.markDirty(); this.tile.setChanged();
if (this.sendToClients && !this.tile.getLevel().isClientSide) if (this.sendToClients && !this.tile.getLevel().isClientSide)
this.tile.sendToClients(); this.tile.sendToClients();
} }

View file

@ -1,117 +0,0 @@
package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.blocks.BlockAutoCrafter;
import de.ellpeck.naturesaura.blocks.multi.Multiblocks;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.block.BlockState;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.Player;
import net.minecraft.inventory.CraftingInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.tileentity.ITickableBlockEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.EntityPredicates;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import java.util.List;
public class BlockEntityAutoCrafter extends BlockEntityImpl implements ITickableBlockEntity {
public final CraftingInventory crafting = new CraftingInventory(new Container(null, 0) {
@Override
public boolean canInteractWith(Player playerIn) {
return false;
}
}, 3, 3);
public BlockEntityAutoCrafter() {
super(ModTileEntities.AUTO_CRAFTER);
}
@Override
public void tick() {
if (!this.level.isClientSide) {
if (this.level.getGameTime() % 60 != 0)
return;
if (!Multiblocks.AUTO_CRAFTER.isComplete(this.level, this.worldPosition))
return;
this.crafting.clear();
BlockState state = this.level.getBlockState(this.worldPosition);
Direction facing = state.get(BlockAutoCrafter.FACING);
BlockPos middlePos = this.worldPosition.up();
BlockPos topPos = middlePos.offset(facing, 2);
BlockPos bottomPos = middlePos.offset(facing.getOpposite(), 2);
BlockPos[] poses = new BlockPos[]{
topPos.offset(facing.rotateYCCW(), 2),
topPos,
topPos.offset(facing.rotateY(), 2),
middlePos.offset(facing.rotateYCCW(), 2),
middlePos,
middlePos.offset(facing.rotateY(), 2),
bottomPos.offset(facing.rotateYCCW(), 2),
bottomPos,
bottomPos.offset(facing.rotateY(), 2)
};
ItemEntity[] items = new ItemEntity[9];
for (int i = 0; i < poses.length; i++) {
List<ItemEntity> entities = this.level.getEntitiesWithinAABB(
ItemEntity.class, new AxisAlignedBB(poses[i]).grow(0.25), EntityPredicates.IS_ALIVE);
if (entities.size() > 1)
return;
if (entities.isEmpty())
continue;
ItemEntity entity = entities.get(0);
if (entity.cannotPickup())
return;
ItemStack stack = entity.getItem();
if (stack.isEmpty())
return;
items[i] = entity;
this.crafting.setInventorySlotContents(i, stack.copy());
}
IRecipe recipe = this.level.getRecipeManager().getRecipe(IRecipeType.CRAFTING, this.crafting, this.level).orElse(null);
if (recipe == null)
return;
ItemStack result = recipe.getCraftingResult(this.crafting);
if (result.isEmpty())
return;
ItemEntity resultItem = new ItemEntity(this.level,
this.worldPosition.getX() + 0.5F, this.worldPosition.getY() - 0.35F, this.worldPosition.getZ() + 0.5F, result.copy());
resultItem.setMotion(0, 0, 0);
this.level.addEntity(resultItem);
NonNullList<ItemStack> remainingItems = recipe.getRemainingItems(this.crafting);
for (int i = 0; i < items.length; i++) {
ItemEntity item = items[i];
if (item == null)
continue;
ItemStack stack = item.getItem();
if (stack.getCount() <= 1)
item.remove();
else {
stack.shrink(1);
item.setItem(stack);
}
ItemStack remain = remainingItems.get(i);
if (!remain.isEmpty()) {
ItemEntity remItem = new ItemEntity(this.level, item.getPosX(), item.getPosY(), item.getPosZ(), remain.copy());
remItem.setMotion(0, 0, 0);
this.level.addEntity(remItem);
}
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32,
new PacketParticles((float) item.getPosX(), (float) item.getPosY(), (float) item.getPosZ(), PacketParticles.Type.ANIMAL_SPAWNER));
}
}
}
}

View file

@ -6,22 +6,27 @@ import de.ellpeck.naturesaura.api.misc.ILevelData;
import de.ellpeck.naturesaura.blocks.BlockEnderCrate; import de.ellpeck.naturesaura.blocks.BlockEnderCrate;
import de.ellpeck.naturesaura.gui.ContainerEnderCrate; import de.ellpeck.naturesaura.gui.ContainerEnderCrate;
import de.ellpeck.naturesaura.gui.ModContainers; import de.ellpeck.naturesaura.gui.ModContainers;
import net.minecraft.core.BlockPos;
import net.minecraft.entity.player.Player; import net.minecraft.entity.player.Player;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.WorldlyContainer;
import net.minecraft.world.inventory.MenuConstructor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.IItemHandlerModifiable;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class BlockEntityEnderCrate extends BlockEntityImpl implements INamedContainerProvider { public class BlockEntityEnderCrate extends BlockEntityImpl implements MenuProvider {
public String name; public String name;
private final IItemHandlerModifiable wrappedEnderStorage = new IItemHandlerModifiable() { private final IItemHandlerModifiable wrappedEnderStorage = new IItemHandlerModifiable() {
@ -74,8 +79,8 @@ public class BlockEntityEnderCrate extends BlockEntityImpl implements INamedCont
} }
}; };
public BlockEntityEnderCrate() { public BlockEntityEnderCrate(BlockPos pos, BlockState state) {
super(ModTileEntities.ENDER_CRATE); super(ModTileEntities.ENDER_CRATE, pos, state);
} }
@Override @Override

View file

@ -1,129 +0,0 @@
package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.blocks.BlockFurnaceHeater;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticleStream;
import net.minecraft.block.AbstractFurnaceBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.AbstractCookingRecipe;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.tileentity.*;
import net.minecraft.util.Direction;
import net.minecraft.util.IIntArray;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Mth;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import java.lang.reflect.Field;
public class BlockEntityFurnaceHeater extends BlockEntityImpl implements ITickableBlockEntity {
private static final Field FURNACE_DATA_FIELD = ObfuscationReflectionHelper.findField(AbstractFurnaceBlockEntity.class, "field_214013_b");
public boolean isActive;
public BlockEntityFurnaceHeater() {
super(ModTileEntities.FURNACE_HEATER);
}
public static IIntArray getFurnaceData(AbstractFurnaceBlockEntity tile) {
try {
return (IIntArray) FURNACE_DATA_FIELD.get(tile);
} catch (IllegalAccessException e) {
NaturesAura.LOGGER.fatal("Couldn't reflect furnace field", e);
return null;
}
}
public static IRecipeType<? extends AbstractCookingRecipe> getRecipeType(AbstractFurnaceBlockEntity furnace) {
if (furnace instanceof BlastFurnaceBlockEntity) {
return IRecipeType.BLASTING;
} else if (furnace instanceof SmokerBlockEntity) {
return IRecipeType.SMOKING;
} else {
return IRecipeType.SMELTING;
}
}
@Override
public void tick() {
if (!this.level.isClientSide && this.level.getGameTime() % 5 == 0) {
boolean did = false;
Direction facing = this.level.getBlockState(this.worldPosition).get(BlockFurnaceHeater.FACING);
BlockPos tilePos = this.worldPosition.offset(facing.getOpposite());
BlockEntity tile = this.level.getBlockEntity(tilePos);
if (tile instanceof AbstractFurnaceBlockEntity) {
AbstractFurnaceBlockEntity furnace = (AbstractFurnaceBlockEntity) tile;
if (this.isReady(furnace)) {
IIntArray data = getFurnaceData(furnace);
int burnTime = data.get(0);
if (burnTime <= 0)
this.level.setBlockState(tilePos, this.level.getBlockState(tilePos).with(AbstractFurnaceBlock.LIT, true));
data.set(0, 200);
//if set higher than 199, it'll never finish because the furnace does ++ and then ==
data.set(2, Math.min(data.get(3) - 1, data.get(2) + 5));
BlockPos spot = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 20, this.worldPosition);
IAuraChunk chunk = IAuraChunk.getAuraChunk(this.level, spot);
chunk.drainAura(spot, Mth.ceil((200 - burnTime) * 16.6F));
did = true;
if (this.level.getGameTime() % 15 == 0) {
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticleStream(
this.worldPosition.getX() + (float) this.level.rand.nextGaussian() * 5F,
this.worldPosition.getY() + 1 + this.level.rand.nextFloat() * 5F,
this.worldPosition.getZ() + (float) this.level.rand.nextGaussian() * 5F,
tilePos.getX() + this.level.rand.nextFloat(),
tilePos.getY() + this.level.rand.nextFloat(),
tilePos.getZ() + this.level.rand.nextFloat(),
this.level.rand.nextFloat() * 0.07F + 0.07F, IAuraType.forLevel(this.level).getColor(), this.level.rand.nextFloat() + 0.5F
));
}
}
}
if (did != this.isActive) {
this.isActive = did;
this.sendToClients();
}
}
}
private boolean isReady(AbstractFurnaceBlockEntity furnace) {
if (!furnace.getStackInSlot(1).isEmpty())
return false;
ItemStack input = furnace.getStackInSlot(0);
if (!input.isEmpty()) {
AbstractCookingRecipe recipe = this.level.getRecipeManager().getRecipe(getRecipeType(furnace), furnace, this.level).orElse(null);
if (recipe == null)
return false;
ItemStack output = recipe.getRecipeOutput();
ItemStack currOutput = furnace.getStackInSlot(2);
return currOutput.isEmpty() || Helper.areItemsEqual(currOutput, output, true) && currOutput.getCount() + output.getCount() <= output.getMaxStackSize();
} else
return false;
}
@Override
public void writeNBT(CompoundTag compound, SaveType type) {
super.writeNBT(compound, type);
if (type == SaveType.SYNC)
compound.putBoolean("active", this.isActive);
}
@Override
public void readNBT(CompoundTag compound, SaveType type) {
super.readNBT(compound, type);
if (type == SaveType.SYNC)
this.isActive = compound.getBoolean("active");
}
}

View file

@ -1,85 +1,37 @@
package de.ellpeck.naturesaura.blocks.tiles.render; package de.ellpeck.naturesaura.blocks.tiles.render;
import com.google.common.collect.ImmutableList; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.IVertexBuilder; import com.mojang.math.Matrix4f;
import de.ellpeck.naturesaura.blocks.tiles.BlockEntityEnderCrate; import de.ellpeck.naturesaura.blocks.tiles.BlockEntityEnderCrate;
import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.tileentity.BlockEntityRenderer; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.tileentity.BlockEntityRendererDispatcher;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public class RenderEnderCrate extends BlockEntityRenderer<BlockEntityEnderCrate> { public class RenderEnderCrate implements BlockEntityRenderer<BlockEntityEnderCrate> {
private static final Random RANDOM = new Random(31100L);
private static final List<RenderType> RENDER_TYPES = IntStream.range(0, 16).mapToObj(i -> RenderType.getEndPortal(i + 1)).collect(ImmutableList.toImmutableList());
public RenderEnderCrate(BlockEntityRendererDispatcher rendererDispatcherIn) {
super(rendererDispatcherIn);
}
@Override @Override
public void render(BlockEntityEnderCrate tileEntityIn, float partialTicks, MatrixStack matrixStackIn, IRenderTypeBuffer bufferIn, int combinedLightIn, int combinedOverlayIn) { public void render(BlockEntityEnderCrate tileEntityIn, float partialTicks, PoseStack matrixStackIn, MultiBufferSource bufferIn, int combinedLightIn, int combinedOverlayIn) {
RANDOM.setSeed(31100L); Matrix4f matrix4f = matrixStackIn.last().pose();
double d0 = tileEntityIn.getPos().distanceSq(this.renderDispatcher.renderInfo.getProjectedView(), true); float f1 = RenderEnderCrate.getOffsetUp();
int i = this.getPasses(d0); RenderEnderCrate.renderFace(matrix4f, bufferIn.getBuffer(RenderEnderCrate.renderType()), f1, f1);
float f = this.getOffset();
Matrix4f matrix4f = matrixStackIn.getLast().getMatrix();
this.renderCube(f, 0.15F, matrix4f, bufferIn.getBuffer(RENDER_TYPES.get(0)));
for (int j = 1; j < i; ++j) {
this.renderCube(f, 2.0F / (float) (18 - j), matrix4f, bufferIn.getBuffer(RENDER_TYPES.get(j)));
}
} }
private void renderCube(float g, float h, Matrix4f mat, IVertexBuilder builder) { private static void renderFace(Matrix4f p_173696_, VertexConsumer p_173697_, float p_173700_, float p_173701_) {
float f = (RANDOM.nextFloat() * 0.5F + 0.1F) * h; p_173697_.vertex(p_173696_, (float) 0.0, p_173700_, (float) 1.0).endVertex();
float f1 = (RANDOM.nextFloat() * 0.5F + 0.4F) * h; p_173697_.vertex(p_173696_, (float) 1.0, p_173700_, (float) 1.0).endVertex();
float f2 = (RANDOM.nextFloat() * 0.5F + 0.5F) * h; p_173697_.vertex(p_173696_, (float) 1.0, p_173701_, (float) 0.0).endVertex();
this.renderFace(mat, builder, g, g, f, f1, f2); p_173697_.vertex(p_173696_, (float) 0.0, p_173701_, (float) 0.0).endVertex();
} }
private void renderFace(Matrix4f mat, IVertexBuilder builder, float h, float i, float n, float o, float p) { private static float getOffsetUp() {
builder.pos(mat, 2 / 16F, h, 14 / 16F).color(n, o, p, 1.0F).endVertex();
builder.pos(mat, 14 / 16F, h, 14 / 16F).color(n, o, p, 1.0F).endVertex();
builder.pos(mat, 14 / 16F, i, 2 / 16F).color(n, o, p, 1.0F).endVertex();
builder.pos(mat, 2 / 16F, i, 2 / 16F).color(n, o, p, 1.0F).endVertex();
}
protected int getPasses(double dist) {
int i;
if (dist > 36864.0D) {
i = 1;
} else if (dist > 25600.0D) {
i = 3;
} else if (dist > 16384.0D) {
i = 5;
} else if (dist > 9216.0D) {
i = 7;
} else if (dist > 4096.0D) {
i = 9;
} else if (dist > 1024.0D) {
i = 11;
} else if (dist > 576.0D) {
i = 13;
} else if (dist > 256.0D) {
i = 14;
} else {
i = 15;
}
return i;
}
protected float getOffset() {
return 1.001F; return 1.001F;
} }
private static RenderType renderType() {
return RenderType.endPortal();
}
} }

View file

@ -1,6 +1,5 @@
package de.ellpeck.naturesaura.entities; package de.ellpeck.naturesaura.entities;
import com.google.common.collect.ListMultimap;
import de.ellpeck.naturesaura.Helper; import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.api.NaturesAuraAPI; import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.misc.ILevelData; import de.ellpeck.naturesaura.api.misc.ILevelData;
@ -8,33 +7,30 @@ import de.ellpeck.naturesaura.api.render.IVisualizable;
import de.ellpeck.naturesaura.items.ItemEffectPowder; import de.ellpeck.naturesaura.items.ItemEffectPowder;
import de.ellpeck.naturesaura.items.ModItems; import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.misc.LevelData; import de.ellpeck.naturesaura.misc.LevelData;
import net.minecraft.entity.Entity; import net.minecraft.core.BlockPos;
import net.minecraft.entity.EntityType;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.IPacket; import net.minecraft.network.protocol.Packet;
import net.minecraft.network.datasync.DataParameter; import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.datasync.DataSerializers; import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.util.DamageSource; import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.EntityDamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Tuple; import net.minecraft.util.Tuple;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.util.math.BlockPos; import net.minecraft.world.damagesource.EntityDamageSource;
import net.minecraft.util.math.vector.Vector3d; import net.minecraft.world.entity.Entity;
import net.minecraft.level.Level; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.network.NetworkHooks;
import java.util.List;
public class EntityEffectInhibitor extends Entity implements IVisualizable { public class EntityEffectInhibitor extends Entity implements IVisualizable {
private static final DataParameter<String> INHIBITED_EFFECT = EntityDataManager.createKey(EntityEffectInhibitor.class, DataSerializers.STRING); private static final EntityDataAccessor<String> INHIBITED_EFFECT = SynchedEntityData.defineId(EntityEffectInhibitor.class, EntityDataSerializers.STRING);
private static final DataParameter<Integer> COLOR = EntityDataManager.createKey(EntityEffectInhibitor.class, DataSerializers.VARINT); private static final EntityDataAccessor<Integer> COLOR = SynchedEntityData.defineId(EntityEffectInhibitor.class, EntityDataSerializers.INT);
private static final DataParameter<Integer> AMOUNT = EntityDataManager.createKey(EntityEffectInhibitor.class, DataSerializers.VARINT); private static final EntityDataAccessor<Integer> AMOUNT = SynchedEntityData.defineId(EntityEffectInhibitor.class, EntityDataSerializers.INT);
private ResourceLocation lastEffect; private ResourceLocation lastEffect;
private boolean powderListDirty; private boolean powderListDirty;
@ -46,47 +42,47 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
} }
public static void place(Level level, ItemStack stack, double posX, double posY, double posZ) { public static void place(Level level, ItemStack stack, double posX, double posY, double posZ) {
ResourceLocation effect = ItemEffectPowder.getEffect(stack); var effect = ItemEffectPowder.getEffect(stack);
EntityEffectInhibitor entity = new EntityEffectInhibitor(ModEntities.EFFECT_INHIBITOR, level); var entity = new EntityEffectInhibitor(ModEntities.EFFECT_INHIBITOR, level);
entity.setInhibitedEffect(effect); entity.setInhibitedEffect(effect);
entity.setColor(NaturesAuraAPI.EFFECT_POWDERS.get(effect)); entity.setColor(NaturesAuraAPI.EFFECT_POWDERS.get(effect));
entity.setAmount(stack.getCount()); entity.setAmount(stack.getCount());
entity.setPosition(posX, posY, posZ); entity.setPos(posX, posY, posZ);
level.addEntity(entity); level.addFreshEntity(entity);
} }
@Override @Override
public void onAddedToLevel() { public void onAddedToWorld() {
super.onAddedToLevel(); super.onAddedToWorld();
this.powderListDirty = true; this.powderListDirty = true;
} }
@Override @Override
public void onRemovedFromLevel() { public void onRemovedFromWorld() {
super.onRemovedFromLevel(); super.onRemovedFromWorld();
this.setInhibitedEffect(null); this.setInhibitedEffect(null);
this.updatePowderListStatus(); this.updatePowderListStatus();
} }
@Override @Override
protected void registerData() { protected void defineSynchedData() {
this.dataManager.register(INHIBITED_EFFECT, null); this.entityData.define(INHIBITED_EFFECT, null);
this.dataManager.register(COLOR, 0); this.entityData.define(COLOR, 0);
this.dataManager.register(AMOUNT, 0); this.entityData.define(AMOUNT, 0);
} }
@Override @Override
public void notifyDataManagerChange(DataParameter<?> key) { public void onSyncedDataUpdated(EntityDataAccessor<?> key) {
super.notifyDataManagerChange(key); super.onSyncedDataUpdated(key);
if (INHIBITED_EFFECT.equals(key) || AMOUNT.equals(key)) if (INHIBITED_EFFECT.equals(key) || AMOUNT.equals(key))
this.powderListDirty = true; this.powderListDirty = true;
} }
@Override @Override
public void setPosition(double x, double y, double z) { public void setPos(double x, double y, double z) {
if (x != this.getPosX() || y != this.getPosY() || z != this.getPosZ()) if (x != this.getX() || y != this.getY() || z != this.getZ())
this.powderListDirty = true; this.powderListDirty = true;
super.setPosition(x, y, z); super.setPos(x, y, z);
} }
@Override @Override
@ -99,13 +95,13 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
if (this.level.isClientSide) { if (this.level.isClientSide) {
if (this.level.getGameTime() % 5 == 0) { if (this.level.getGameTime() % 5 == 0) {
NaturesAuraAPI.instance().spawnMagicParticle( NaturesAuraAPI.instance().spawnMagicParticle(
this.getPosX() + this.level.rand.nextGaussian() * 0.1F, this.getX() + this.level.random.nextGaussian() * 0.1F,
this.getPosY(), this.getY(),
this.getPosZ() + this.level.rand.nextGaussian() * 0.1F, this.getZ() + this.level.random.nextGaussian() * 0.1F,
this.level.rand.nextGaussian() * 0.005F, this.level.random.nextGaussian() * 0.005F,
this.level.rand.nextFloat() * 0.03F, this.level.random.nextFloat() * 0.03F,
this.level.rand.nextGaussian() * 0.005F, this.level.random.nextGaussian() * 0.005F,
this.getColor(), this.level.rand.nextFloat() * 3F + 1F, 120, 0F, true, true); this.getColor(), this.level.random.nextFloat() * 3F + 1F, 120, 0F, true, true);
} }
this.renderTicks++; this.renderTicks++;
} }
@ -117,32 +113,32 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
} }
@Override @Override
protected void readAdditional(CompoundTag compound) { protected void readAdditionalSaveData(CompoundTag compound) {
this.setInhibitedEffect(new ResourceLocation(compound.getString("effect"))); this.setInhibitedEffect(new ResourceLocation(compound.getString("effect")));
this.setColor(compound.getInt("color")); this.setColor(compound.getInt("color"));
this.setAmount(compound.contains("amount") ? compound.getInt("amount") : 24); this.setAmount(compound.contains("amount") ? compound.getInt("amount") : 24);
} }
@Override @Override
protected void writeAdditional(CompoundTag compound) { protected void addAdditionalSaveData(CompoundTag compound) {
compound.putString("effect", this.getInhibitedEffect().toString()); compound.putString("effect", this.getInhibitedEffect().toString());
compound.putInt("color", this.getColor()); compound.putInt("color", this.getColor());
compound.putInt("amount", this.getAmount()); compound.putInt("amount", this.getAmount());
} }
@Override @Override
public IPacket<?> createSpawnPacket() { public Packet<?> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this); return NetworkHooks.getEntitySpawningPacket(this);
} }
@Override @Override
public boolean attackEntityFrom(DamageSource source, float amount) { public boolean hurt(DamageSource source, float amount) {
if (source instanceof EntityDamageSource && !this.level.isClientSide) { if (source instanceof EntityDamageSource && !this.level.isClientSide) {
this.remove(); this.kill();
this.entityDropItem(this.getDrop(), 0F); this.spawnAtLocation(this.getDrop(), 0F);
return true; return true;
} else } else
return super.attackEntityFrom(source, amount); return super.hurt(source, amount);
} }
public ItemStack getDrop() { public ItemStack getDrop() {
@ -150,36 +146,36 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
} }
public ResourceLocation getInhibitedEffect() { public ResourceLocation getInhibitedEffect() {
String effect = this.dataManager.get(INHIBITED_EFFECT); var effect = this.entityData.get(INHIBITED_EFFECT);
if (effect == null || effect.isEmpty()) if (effect == null || effect.isEmpty())
return null; return null;
return new ResourceLocation(effect); return new ResourceLocation(effect);
} }
public void setInhibitedEffect(ResourceLocation effect) { public void setInhibitedEffect(ResourceLocation effect) {
this.dataManager.set(INHIBITED_EFFECT, effect != null ? effect.toString() : null); this.entityData.set(INHIBITED_EFFECT, effect != null ? effect.toString() : null);
} }
public int getColor() { public int getColor() {
return this.dataManager.get(COLOR); return this.entityData.get(COLOR);
} }
public void setColor(int color) { public void setColor(int color) {
this.dataManager.set(COLOR, color); this.entityData.set(COLOR, color);
} }
public int getAmount() { public int getAmount() {
return this.dataManager.get(AMOUNT); return this.entityData.get(AMOUNT);
} }
public void setAmount(int amount) { public void setAmount(int amount) {
this.dataManager.set(AMOUNT, amount); this.entityData.set(AMOUNT, amount);
} }
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public AxisAlignedBB getVisualizationBounds(Level level, BlockPos pos) { public AABB getVisualizationBounds(Level level, BlockPos pos) {
return Helper.aabb(this.getPositionVec()).grow(this.getAmount()); return Helper.aabb(this.getEyePosition()).inflate(this.getAmount());
} }
@Override @Override
@ -189,15 +185,15 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
} }
private void updatePowderListStatus() { private void updatePowderListStatus() {
ListMultimap<ResourceLocation, Tuple<Vector3d, Integer>> powders = ((LevelData) ILevelData.getLevelData(this.level)).effectPowders; var powders = ((LevelData) ILevelData.getLevelData(this.level)).effectPowders;
if (this.lastEffect != null) { if (this.lastEffect != null) {
List<Tuple<Vector3d, Integer>> oldList = powders.get(this.lastEffect); var oldList = powders.get(this.lastEffect);
oldList.removeIf(t -> this.getPositionVec().equals(t.getA())); oldList.removeIf(t -> this.getEyePosition().equals(t.getA()));
} }
ResourceLocation effect = this.getInhibitedEffect(); var effect = this.getInhibitedEffect();
if (effect != null) { if (effect != null) {
List<Tuple<Vector3d, Integer>> newList = powders.get(effect); var newList = powders.get(effect);
newList.add(new Tuple<>(this.getPositionVec(), this.getAmount())); newList.add(new Tuple<>(this.getEyePosition(), this.getAmount()));
} }
this.powderListDirty = false; this.powderListDirty = false;
this.lastEffect = effect; this.lastEffect = effect;

View file

@ -4,34 +4,33 @@ import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.items.ModItems; import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.packet.PacketHandler; import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles; import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.block.BlockState; import net.minecraft.core.BlockPos;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.INBT; import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.LongTag;
import net.minecraft.nbt.LongNBT; import net.minecraft.nbt.Tag;
import net.minecraft.network.IPacket; import net.minecraft.network.protocol.Packet;
import net.minecraft.util.DamageSource; import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.Mth;
import net.minecraft.util.math.Mth; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.entity.Entity;
import net.minecraft.util.math.vector.Vector3d; import net.minecraft.world.entity.EntityType;
import net.minecraft.level.GameRules; import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.level.Level; import net.minecraft.world.item.ItemStack;
import net.minecraft.level.server.ServerLevel; import net.minecraft.world.level.GameRules;
import net.minecraftforge.common.util.Constants; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.util.ITeleporter; import net.minecraftforge.common.util.ITeleporter;
import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.network.NetworkHooks;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class EntityMoverMinecart extends AbstractMinecartEntity { public class EntityMoverMinecart extends AbstractMinecart {
private final List<BlockPos> spotOffsets = new ArrayList<>(); private final List<BlockPos> spotOffsets = new ArrayList<>();
public boolean isActive; public boolean isActive;
@ -50,14 +49,14 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
super.moveMinecartOnRail(railPos); super.moveMinecartOnRail(railPos);
if (!this.isActive) if (!this.isActive)
return; return;
BlockPos pos = this.getPosition(); BlockPos pos = this.getOnPos();
if (!this.spotOffsets.isEmpty() && this.level.getGameTime() % 10 == 0) if (!this.spotOffsets.isEmpty() && this.level.getGameTime() % 10 == 0)
PacketHandler.sendToAllAround(this.level, pos, 32, new PacketParticles( PacketHandler.sendToAllAround(this.level, pos, 32, new PacketParticles(
(float) this.getPosX(), (float) this.getPosY(), (float) this.getPosZ(), PacketParticles.Type.MOVER_CART, (float) this.getX(), (float) this.getY(), (float) this.getZ(), PacketParticles.Type.MOVER_CART,
Mth.floor(this.getMotion().getX() * 100F), Mth.floor(this.getMotion().getY() * 100F), Mth.floor(this.getMotion().getZ() * 100F))); Mth.floor(this.getDeltaMovement().x * 100F), Mth.floor(this.getDeltaMovement().y * 100F), Mth.floor(this.getDeltaMovement().z * 100F)));
if (pos.distanceSq(this.lastPosition) < 8 * 8) if (pos.distSqr(this.lastPosition) < 8 * 8)
return; return;
this.moveAura(this.level, this.lastPosition, this.level, pos); this.moveAura(this.level, this.lastPosition, this.level, pos);
@ -66,7 +65,7 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
private void moveAura(Level oldLevel, BlockPos oldPos, Level newLevel, BlockPos newPos) { private void moveAura(Level oldLevel, BlockPos oldPos, Level newLevel, BlockPos newPos) {
for (BlockPos offset : this.spotOffsets) { for (BlockPos offset : this.spotOffsets) {
BlockPos spot = oldPos.add(offset); BlockPos spot = oldPos.offset(offset);
IAuraChunk chunk = IAuraChunk.getAuraChunk(oldLevel, spot); IAuraChunk chunk = IAuraChunk.getAuraChunk(oldLevel, spot);
int amount = chunk.getDrainSpot(spot); int amount = chunk.getDrainSpot(spot);
if (amount <= 0) if (amount <= 0)
@ -76,17 +75,17 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
if (drained <= 0) if (drained <= 0)
continue; continue;
int toLose = Mth.ceil(drained / 250F); int toLose = Mth.ceil(drained / 250F);
BlockPos newSpot = newPos.add(offset); BlockPos newSpot = newPos.offset(offset);
IAuraChunk.getAuraChunk(newLevel, newSpot).storeAura(newSpot, drained - toLose, false, false); IAuraChunk.getAuraChunk(newLevel, newSpot).storeAura(newSpot, drained - toLose, false, false);
} }
} }
@Override @Override
public void onActivatorRailPass(int x, int y, int z, boolean receivingPower) { public void activateMinecart(int x, int y, int z, boolean receivingPower) {
if (this.isActive != receivingPower) { if (this.isActive != receivingPower) {
this.isActive = receivingPower; this.isActive = receivingPower;
BlockPos pos = this.getPosition(); BlockPos pos = this.getOnPos();
if (!this.isActive) { if (!this.isActive) {
this.moveAura(this.level, this.lastPosition, this.level, pos); this.moveAura(this.level, this.lastPosition, this.level, pos);
this.spotOffsets.clear(); this.spotOffsets.clear();
@ -103,21 +102,21 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
} }
@Override @Override
public void killMinecart(DamageSource source) { public void destroy(DamageSource source) {
this.remove(); this.kill();
if (this.level.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) if (this.level.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS))
this.entityDropItem(new ItemStack(ModItems.MOVER_CART), 0); this.spawnAtLocation(new ItemStack(ModItems.MOVER_CART), 0);
} }
@Override @Override
public CompoundTag serializeNBT() { public CompoundTag serializeNBT() {
CompoundTag compound = super.serializeNBT(); CompoundTag compound = super.serializeNBT();
compound.putBoolean("active", this.isActive); compound.putBoolean("active", this.isActive);
compound.putLong("last_pos", this.lastPosition.toLong()); compound.putLong("last_pos", this.lastPosition.asLong());
ListNBT list = new ListNBT(); ListTag list = new ListTag();
for (BlockPos offset : this.spotOffsets) for (BlockPos offset : this.spotOffsets)
list.add(LongNBT.valueOf(offset.toLong())); list.add(LongTag.valueOf(offset.asLong()));
compound.put("offsets", list); compound.put("offsets", list);
return compound; return compound;
} }
@ -126,12 +125,12 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
public void deserializeNBT(CompoundTag compound) { public void deserializeNBT(CompoundTag compound) {
super.deserializeNBT(compound); super.deserializeNBT(compound);
this.isActive = compound.getBoolean("active"); this.isActive = compound.getBoolean("active");
this.lastPosition = BlockPos.fromLong(compound.getLong("last_pos")); this.lastPosition = BlockPos.of(compound.getLong("last_pos"));
this.spotOffsets.clear(); this.spotOffsets.clear();
ListNBT list = compound.getList("offsets", Constants.NBT.TAG_LONG); ListTag list = compound.getList("offsets", Tag.TAG_LONG);
for (INBT base : list) for (Tag base : list)
this.spotOffsets.add(BlockPos.fromLong(((LongNBT) base).getLong())); this.spotOffsets.add(BlockPos.of(((LongTag) base).getAsLong()));
} }
@Nullable @Nullable
@ -139,7 +138,7 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
public Entity changeDimension(ServerLevel destination, ITeleporter teleporter) { public Entity changeDimension(ServerLevel destination, ITeleporter teleporter) {
Entity entity = super.changeDimension(destination, teleporter); Entity entity = super.changeDimension(destination, teleporter);
if (entity instanceof EntityMoverMinecart) { if (entity instanceof EntityMoverMinecart) {
BlockPos pos = entity.getPosition(); BlockPos pos = entity.getOnPos();
this.moveAura(this.level, this.lastPosition, entity.level, pos); this.moveAura(this.level, this.lastPosition, entity.level, pos);
((EntityMoverMinecart) entity).lastPosition = pos; ((EntityMoverMinecart) entity).lastPosition = pos;
} }
@ -147,8 +146,8 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
} }
@Override @Override
public BlockState getDisplayTile() { public BlockState getDisplayBlockState() {
return Blocks.STONE.getDefaultState(); return Blocks.STONE.defaultBlockState();
} }
@Override @Override
@ -162,7 +161,7 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
} }
@Override @Override
public ItemStack getPickedResult(RayTraceResult target) { public ItemStack getPickedResult(HitResult target) {
return new ItemStack(ModItems.MOVER_CART); return new ItemStack(ModItems.MOVER_CART);
} }
@ -172,13 +171,13 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
} }
@Override @Override
protected void applyDrag() { protected void applyNaturalSlowdown() {
Vector3d motion = this.getMotion(); Vec3 motion = this.getDeltaMovement();
this.setMotion(motion.x * 0.99F, 0, motion.z * 0.99F); this.setDeltaMovement(motion.x * 0.99F, 0, motion.z * 0.99F);
} }
@Override @Override
public IPacket<?> createSpawnPacket() { public Packet<?> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this); return NetworkHooks.getEntitySpawningPacket(this);
} }
} }

View file

@ -1,9 +1,10 @@
package de.ellpeck.naturesaura.entities; package de.ellpeck.naturesaura.entities;
import net.minecraft.entity.EntityType; import net.minecraft.world.entity.EntityType;
@SuppressWarnings("FieldNamingConvention") @SuppressWarnings("FieldNamingConvention")
public final class ModEntities { public final class ModEntities {
public static EntityType<EntityMoverMinecart> MOVER_CART; public static EntityType<EntityMoverMinecart> MOVER_CART;
public static EntityType<EntityEffectInhibitor> EFFECT_INHIBITOR; public static EntityType<EntityEffectInhibitor> EFFECT_INHIBITOR;
public static EntityType<EntityLightProjectile> LIGHT_PROJECTILE; public static EntityType<EntityLightProjectile> LIGHT_PROJECTILE;

View file

@ -8,12 +8,11 @@ import de.ellpeck.naturesaura.reg.ICustomItemModel;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.client.renderer.color.IItemColor; import net.minecraft.client.renderer.color.IItemColor;
import net.minecraft.entity.player.Player; import net.minecraft.entity.player.Player;
import net.minecraft.item.DyeColor;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext; import net.minecraft.item.ItemUseContext;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.level.Level; import net.minecraft.level.Level;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;

View file

@ -3,17 +3,17 @@ package de.ellpeck.naturesaura.items;
import de.ellpeck.naturesaura.api.NaturesAuraAPI; import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.entities.EntityEffectInhibitor; import de.ellpeck.naturesaura.entities.EntityEffectInhibitor;
import de.ellpeck.naturesaura.reg.IColorProvidingItem; import de.ellpeck.naturesaura.reg.IColorProvidingItem;
import net.minecraft.client.renderer.color.IItemColor; import net.minecraft.client.color.item.ItemColor;
import net.minecraft.item.ItemGroup; import net.minecraft.core.NonNullList;
import net.minecraft.item.ItemStack; import net.minecraft.network.chat.Component;
import net.minecraft.item.ItemUseContext; import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.util.InteractionResult; import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.NonNullList; import net.minecraft.world.InteractionResult;
import net.minecraft.util.ResourceLocation; import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.util.math.vector.Vector3d; import net.minecraft.world.item.ItemStack;
import net.minecraft.util.text.ITextComponent; import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.world.level.Level;
import net.minecraft.level.Level; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
@ -38,11 +38,11 @@ public class ItemEffectPowder extends ItemImpl implements IColorProvidingItem {
} }
@Override @Override
public InteractionResult onItemUse(ItemUseContext context) { public InteractionResult useOn(UseOnContext context) {
Level level = context.getLevel(); Level level = context.getLevel();
if (!level.isClientSide) { if (!level.isClientSide) {
Vector3d hit = context.getHitVec(); Vec3 hit = context.getClickLocation();
ItemStack stack = context.getPlayer().getHeldItem(context.getHand()); ItemStack stack = context.getPlayer().getItemInHand(context.getHand());
EntityEffectInhibitor.place(level, stack, hit.x, hit.y + 1, hit.z); EntityEffectInhibitor.place(level, stack, hit.x, hit.y + 1, hit.z);
stack.setCount(0); stack.setCount(0);
} }
@ -50,8 +50,8 @@ public class ItemEffectPowder extends ItemImpl implements IColorProvidingItem {
} }
@Override @Override
public void fillItemGroup(ItemGroup tab, NonNullList<ItemStack> items) { public void fillItemCategory(CreativeModeTab tab, NonNullList<ItemStack> items) {
if (this.isInGroup(tab)) { if (this.allowdedIn(tab)) {
for (ResourceLocation effect : NaturesAuraAPI.EFFECT_POWDERS.keySet()) { for (ResourceLocation effect : NaturesAuraAPI.EFFECT_POWDERS.keySet()) {
ItemStack stack = new ItemStack(this); ItemStack stack = new ItemStack(this);
setEffect(stack, effect); setEffect(stack, effect);
@ -61,13 +61,13 @@ public class ItemEffectPowder extends ItemImpl implements IColorProvidingItem {
} }
@Override @Override
public ITextComponent getDisplayName(ItemStack stack) { public Component getName(ItemStack stack) {
return new TranslationTextComponent(this.getTranslationKey(stack) + "." + getEffect(stack)); return new TranslatableComponent(this.getDescriptionId(stack) + "." + getEffect(stack));
} }
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public IItemColor getItemColor() { public ItemColor getItemColor() {
return (stack, tintIndex) -> NaturesAuraAPI.EFFECT_POWDERS.getOrDefault(getEffect(stack), 0xFFFFFF); return (stack, tintIndex) -> NaturesAuraAPI.EFFECT_POWDERS.getOrDefault(getEffect(stack), 0xFFFFFF);
} }
} }

View file

@ -2,10 +2,10 @@ package de.ellpeck.naturesaura.particles;
import com.mojang.blaze3d.vertex.IVertexBuilder; import com.mojang.blaze3d.vertex.IVertexBuilder;
import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.NaturesAura;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.particle.IParticleRenderType; import net.minecraft.client.particle.IParticleRenderType;
import net.minecraft.client.particle.Particle; import net.minecraft.client.particle.Particle;
import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.level.ClientLevel;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.ReuseableStream; import net.minecraft.util.ReuseableStream;

View file

@ -12,31 +12,25 @@ import de.ellpeck.naturesaura.particles.ParticleMagic;
import de.ellpeck.naturesaura.reg.*; import de.ellpeck.naturesaura.reg.*;
import de.ellpeck.naturesaura.renderers.PlayerLayerTrinkets; import de.ellpeck.naturesaura.renderers.PlayerLayerTrinkets;
import de.ellpeck.naturesaura.renderers.SupporterFancyHandler; import de.ellpeck.naturesaura.renderers.SupporterFancyHandler;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScreenManager; import net.minecraft.client.color.item.ItemColor;
import net.minecraft.client.renderer.RenderTypeLookup; import net.minecraft.client.color.item.ItemColors;
import net.minecraft.client.renderer.color.IItemColor; import net.minecraft.client.gui.screens.MenuScreens;
import net.minecraft.client.renderer.color.ItemColors; import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.entity.PlayerRenderer; import net.minecraft.client.renderer.blockentity.BlockEntityRenderers;
import net.minecraft.client.renderer.tileentity.BlockEntityRenderer; import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.tileentity.BlockEntityRendererDispatcher; import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.entity.Entity; import net.minecraft.client.renderer.entity.EntityRenderers;
import net.minecraft.entity.EntityType; import net.minecraft.client.renderer.entity.player.PlayerRenderer;
import net.minecraft.item.Item; import net.minecraft.client.renderer.item.ItemProperties;
import net.minecraft.item.ItemModelsProperties; import net.minecraft.resources.ResourceLocation;
import net.minecraft.tileentity.BlockEntity; import net.minecraft.world.entity.Entity;
import net.minecraft.tileentity.BlockEntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.util.ResourceLocation; import net.minecraft.world.item.Item;
import net.minecraft.util.Tuple; import net.minecraft.world.level.block.Block;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.client.registry.IRenderFactory;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
public class ClientProxy implements IProxy { public class ClientProxy implements IProxy {
@ -45,20 +39,22 @@ public class ClientProxy implements IProxy {
public void preInit(FMLCommonSetupEvent event) { public void preInit(FMLCommonSetupEvent event) {
MinecraftForge.EVENT_BUS.register(new ClientEvents()); MinecraftForge.EVENT_BUS.register(new ClientEvents());
Compat.setupClient(); Compat.setupClient();
ScreenManager.registerFactory(ModContainers.ENDER_CRATE, GuiEnderCrate::new); MenuScreens.register(ModContainers.ENDER_CRATE, GuiEnderCrate::new);
ScreenManager.registerFactory(ModContainers.ENDER_ACCESS, GuiEnderCrate::new); MenuScreens.register(ModContainers.ENDER_ACCESS, GuiEnderCrate::new);
ItemModelsProperties.func_239418_a_(ModItems.COLOR_CHANGER, new ResourceLocation(NaturesAura.MOD_ID, "fill_mode"), ItemProperties.register(ModItems.COLOR_CHANGER, new ResourceLocation(NaturesAura.MOD_ID, "fill_mode"),
(stack, levelIn, entityIn) -> ItemColorChanger.isFillMode(stack) ? 1F : 0F); (stack, levelIn, entityIn) -> ItemColorChanger.isFillMode(stack) ? 1F : 0F);
ItemModelsProperties.func_239418_a_(ModItems.COLOR_CHANGER, new ResourceLocation(NaturesAura.MOD_ID, "has_color"), ItemProperties.register(ModItems.COLOR_CHANGER, new ResourceLocation(NaturesAura.MOD_ID, "has_color"),
(stack, levelIn, entityIn) -> ItemColorChanger.getStoredColor(stack) != null ? 1F : 0F); (stack, levelIn, entityIn) -> ItemColorChanger.getStoredColor(stack) != null ? 1F : 0F);
} }
@Override @Override
public void init(FMLCommonSetupEvent event) { public void init(FMLCommonSetupEvent event) {
Map<String, PlayerRenderer> skinMap = Minecraft.getInstance().getRenderManager().getSkinMap(); var skinMap = Minecraft.getInstance().getEntityRenderDispatcher().getSkinMap();
for (PlayerRenderer render : new PlayerRenderer[]{skinMap.get("default"), skinMap.get("slim")}) for (var render : new EntityRenderer[]{skinMap.get("default"), skinMap.get("slim")}) {
render.addLayer(new PlayerLayerTrinkets(render)); if (render instanceof PlayerRenderer living)
living.addLayer(new PlayerLayerTrinkets(living));
}
new SupporterFancyHandler(); new SupporterFancyHandler();
} }
@ -66,14 +62,14 @@ public class ClientProxy implements IProxy {
public void postInit(FMLCommonSetupEvent event) { public void postInit(FMLCommonSetupEvent event) {
for (IModItem item : ModRegistry.ALL_ITEMS) { for (IModItem item : ModRegistry.ALL_ITEMS) {
if (item instanceof ICustomRenderType) if (item instanceof ICustomRenderType)
RenderTypeLookup.setRenderLayer((Block) item, ((ICustomRenderType) item).getRenderType().get()); ItemBlockRenderTypes.setRenderLayer((Block) item, ((ICustomRenderType) item).getRenderType().get());
} }
} }
@Override @Override
public void addColorProvidingItem(IColorProvidingItem item) { public void addColorProvidingItem(IColorProvidingItem item) {
ItemColors colors = Minecraft.getInstance().getItemColors(); ItemColors colors = Minecraft.getInstance().getItemColors();
IItemColor color = item.getItemColor(); ItemColor color = item.getItemColor();
if (item instanceof Item) { if (item instanceof Item) {
colors.register(color, (Item) item); colors.register(color, (Item) item);
@ -84,15 +80,14 @@ public class ClientProxy implements IProxy {
@Override @Override
public void addColorProvidingBlock(IColorProvidingBlock block) { public void addColorProvidingBlock(IColorProvidingBlock block) {
if (block instanceof Block) { if (block instanceof Block)
Minecraft.getInstance().getBlockColors().register(block.getBlockColor(), (Block) block); Minecraft.getInstance().getBlockColors().register(block.getBlockColor(), (Block) block);
}
} }
@Override @Override
public void registerTESR(ITESRProvider provider) { public void registerTESR(ITESRProvider<?> provider) {
Tuple<BlockEntityType<BlockEntity>, Supplier<Function<? super BlockEntityRendererDispatcher, ? extends BlockEntityRenderer<? super BlockEntity>>>> tesr = provider.getTESR(); var tesr = provider.getTESR();
ClientRegistry.bindBlockEntityRenderer(tesr.getA(), tesr.getB().get()); BlockEntityRenderers.register(tesr.getA(), tesr.getB().get());
} }
@Override @Override
@ -119,8 +114,8 @@ public class ClientProxy implements IProxy {
} }
@Override @Override
public <T extends Entity> void registerEntityRenderer(EntityType<T> entityClass, Supplier<IRenderFactory<T>> renderFactory) { public <T extends Entity> void registerEntityRenderer(EntityType<T> entityClass, Supplier<EntityRendererProvider<T>> renderFactory) {
RenderingRegistry.registerEntityRenderingHandler(entityClass, renderFactory.get()); EntityRenderers.register(entityClass, renderFactory.get());
} }
} }

View file

@ -3,14 +3,15 @@ package de.ellpeck.naturesaura.proxy;
import de.ellpeck.naturesaura.reg.IColorProvidingBlock; import de.ellpeck.naturesaura.reg.IColorProvidingBlock;
import de.ellpeck.naturesaura.reg.IColorProvidingItem; import de.ellpeck.naturesaura.reg.IColorProvidingItem;
import de.ellpeck.naturesaura.reg.ITESRProvider; import de.ellpeck.naturesaura.reg.ITESRProvider;
import net.minecraft.entity.Entity; import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.entity.EntityType; import net.minecraft.world.entity.Entity;
import net.minecraftforge.fml.client.registry.IRenderFactory; import net.minecraft.world.entity.EntityType;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import java.util.function.Supplier; import java.util.function.Supplier;
public interface IProxy { public interface IProxy {
void preInit(FMLCommonSetupEvent event); void preInit(FMLCommonSetupEvent event);
void init(FMLCommonSetupEvent event); void init(FMLCommonSetupEvent event);
@ -21,7 +22,7 @@ public interface IProxy {
void addColorProvidingBlock(IColorProvidingBlock block); void addColorProvidingBlock(IColorProvidingBlock block);
void registerTESR(ITESRProvider provider); void registerTESR(ITESRProvider<?> provider);
void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade); void spawnMagicParticle(double posX, double posY, double posZ, double motionX, double motionY, double motionZ, int color, float scale, int maxAge, float gravity, boolean collision, boolean fade);
@ -31,6 +32,5 @@ public interface IProxy {
void setParticleCulling(boolean cull); void setParticleCulling(boolean cull);
<T extends Entity> void registerEntityRenderer(EntityType<T> entityClass, Supplier<IRenderFactory<T>> renderFactory); <T extends Entity> void registerEntityRenderer(EntityType<T> entityClass, Supplier<EntityRendererProvider<T>> renderFactory);
} }

View file

@ -1,12 +1,12 @@
package de.ellpeck.naturesaura.reg; package de.ellpeck.naturesaura.reg;
import net.minecraft.client.renderer.color.IBlockColor; import net.minecraft.client.color.block.BlockColor;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
public interface IColorProvidingBlock { public interface IColorProvidingBlock {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
IBlockColor getBlockColor(); BlockColor getBlockColor();
} }

View file

@ -1,19 +1,17 @@
package de.ellpeck.naturesaura.reg; package de.ellpeck.naturesaura.reg;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.util.Tuple; import net.minecraft.util.Tuple;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
public interface ITESRProvider<T extends BlockEntity> { public interface ITESRProvider<T extends BlockEntity> {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
Tuple<BlockEntityType<T>, Supplier<Function<? super BlockEntityRenderDispatcher, ? extends BlockEntityRenderer<? super T>>>> getTESR(); Tuple<BlockEntityType<BlockEntity>, Supplier<BlockEntityRendererProvider<BlockEntity>>> getTESR();
} }

View file

@ -1,85 +1,83 @@
package de.ellpeck.naturesaura.renderers; package de.ellpeck.naturesaura.renderers;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
import de.ellpeck.naturesaura.ModConfig; import de.ellpeck.naturesaura.ModConfig;
import de.ellpeck.naturesaura.api.render.ITrinketItem; import de.ellpeck.naturesaura.api.render.ITrinketItem;
import de.ellpeck.naturesaura.api.render.ITrinketItem.RenderType; import de.ellpeck.naturesaura.api.render.ITrinketItem.RenderType;
import de.ellpeck.naturesaura.compat.Compat; import net.minecraft.client.model.PlayerModel;
import net.minecraft.client.entity.player.AbstractClientPlayer; import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.IEntityRenderer; import net.minecraft.client.renderer.entity.RenderLayerParent;
import net.minecraft.client.renderer.entity.layers.LayerRenderer; import net.minecraft.client.renderer.entity.layers.RenderLayer;
import net.minecraft.client.renderer.entity.model.PlayerModel; import net.minecraft.world.effect.MobEffects;
import net.minecraft.entity.Pose; import net.minecraft.world.entity.Pose;
import net.minecraft.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.potion.Effects;
import net.minecraft.util.math.vector.Vector3f;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.IItemHandler;
import top.theillusivec4.curios.api.CuriosApi;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public class PlayerLayerTrinkets extends LayerRenderer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>> { public class PlayerLayerTrinkets extends RenderLayer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>> {
private final Set<Item> alreadyRendered = new HashSet<>(); private final Set<Item> alreadyRendered = new HashSet<>();
public PlayerLayerTrinkets(IEntityRenderer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>> entityRendererIn) { public PlayerLayerTrinkets(RenderLayerParent<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>> p_117346_) {
super(entityRendererIn); super(p_117346_);
} }
@Override @Override
public void render(MatrixStack matrixStackIn, IRenderTypeBuffer bufferIn, int packedLightIn, AbstractClientPlayer player, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch) { public void render(PoseStack matrixStackIn, MultiBufferSource bufferIn, int packedLightIn, AbstractClientPlayer player, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch) {
if (!ModConfig.instance.renderItemsOnPlayer.get()) if (!ModConfig.instance.renderItemsOnPlayer.get())
return; return;
if (player.getActivePotionEffect(Effects.INVISIBILITY) != null) if (player.getEffect(MobEffects.INVISIBILITY) != null)
return; return;
ItemStack main = player.getHeldItemMainhand(); var main = player.getMainHandItem();
ItemStack second = player.getHeldItemOffhand(); var second = player.getOffhandItem();
this.alreadyRendered.clear(); this.alreadyRendered.clear();
matrixStackIn.push(); matrixStackIn.pushPose();
this.render(player, RenderType.BODY, main, second, matrixStackIn, bufferIn, packedLightIn); this.render(player, RenderType.BODY, main, second, matrixStackIn, bufferIn, packedLightIn);
float yaw = player.prevRotationYawHead + (player.rotationYawHead - player.prevRotationYawHead) * partialTicks; var yaw = player.yHeadRotO + (player.yHeadRot - player.yHeadRotO) * partialTicks;
float yawOffset = player.prevRenderYawOffset + (player.renderYawOffset - player.prevRenderYawOffset) * partialTicks; var yawOffset = player.yBodyRotO + (player.yBodyRot - player.yBodyRotO) * partialTicks;
float pitch = player.prevRotationPitch + (player.rotationPitch - player.prevRotationPitch) * partialTicks; var pitch = player.xRotO + (player.getXRot() - player.xRotO) * partialTicks;
matrixStackIn.rotate(Vector3f.YN.rotationDegrees(yawOffset)); matrixStackIn.mulPose(Vector3f.YN.rotationDegrees(yawOffset));
matrixStackIn.rotate(Vector3f.YP.rotationDegrees(yaw - 270)); matrixStackIn.mulPose(Vector3f.YP.rotationDegrees(yaw - 270));
matrixStackIn.rotate(Vector3f.ZP.rotationDegrees(pitch)); matrixStackIn.mulPose(Vector3f.ZP.rotationDegrees(pitch));
this.render(player, RenderType.HEAD, main, second, matrixStackIn, bufferIn, packedLightIn); this.render(player, RenderType.HEAD, main, second, matrixStackIn, bufferIn, packedLightIn);
matrixStackIn.pop(); matrixStackIn.popPose();
} }
private void render(Player player, RenderType type, ItemStack main, ItemStack second, MatrixStack matrices, IRenderTypeBuffer buffer, int packedLight) { private void render(Player player, RenderType type, ItemStack main, ItemStack second, PoseStack matrices, MultiBufferSource buffer, int packedLight) {
for (int i = 0; i < player.inventory.getSizeInventory(); i++) { for (var i = 0; i < player.getInventory().getContainerSize(); i++) {
this.renderStack(player.inventory.getStackInSlot(i), player, type, main, second, matrices, buffer, packedLight); this.renderStack(player.getInventory().getItem(i), player, type, main, second, matrices, buffer, packedLight);
} }
if (Compat.hasCompat("curios")) { // TODO Curios
/* if (Compat.hasCompat("curios")) {
IItemHandler handler = CuriosApi.getCuriosHelper().getEquippedCurios(player).orElse(null); IItemHandler handler = CuriosApi.getCuriosHelper().getEquippedCurios(player).orElse(null);
if (handler != null) { if (handler != null) {
for (int i = 0; i < handler.getSlots(); i++) for (int i = 0; i < handler.getSlots(); i++)
this.renderStack(handler.getStackInSlot(i), player, type, main, second, matrices, buffer, packedLight); this.renderStack(handler.getStackInSlot(i), player, type, main, second, matrices, buffer, packedLight);
} }
} }*/
} }
private void renderStack(ItemStack stack, Player player, RenderType type, ItemStack main, ItemStack second, MatrixStack matrices, IRenderTypeBuffer buffer, int packedLight) { private void renderStack(ItemStack stack, Player player, RenderType type, ItemStack main, ItemStack second, PoseStack matrices, MultiBufferSource buffer, int packedLight) {
if (!stack.isEmpty()) { if (!stack.isEmpty()) {
Item item = stack.getItem(); var item = stack.getItem();
if (item instanceof ITrinketItem && !this.alreadyRendered.contains(item)) { if (item instanceof ITrinketItem && !this.alreadyRendered.contains(item)) {
matrices.push(); matrices.pushPose();
if (type == RenderType.BODY && player.getPose() == Pose.CROUCHING) { if (type == RenderType.BODY && player.getPose() == Pose.CROUCHING) {
matrices.translate(0F, 0.2F, 0F); matrices.translate(0F, 0.2F, 0F);
matrices.rotate(Vector3f.XP.rotationDegrees(90F / (float) Math.PI)); matrices.mulPose(Vector3f.XP.rotationDegrees(90F / (float) Math.PI));
} }
((ITrinketItem) item).render(stack, player, type, matrices, buffer, packedLight, stack == main || stack == second); ((ITrinketItem) item).render(stack, player, type, matrices, buffer, packedLight, stack == main || stack == second);
matrices.pop(); matrices.popPose();
this.alreadyRendered.add(item); this.alreadyRendered.add(item);
} }
} }