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;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.entity.player.Player;
import net.minecraft.item.ItemStack;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public interface ITrinketItem {
@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 {
HEAD, BODY

View file

@ -1,15 +1,15 @@
package de.ellpeck.naturesaura.api.render;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.level.Level;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public interface IVisualizable {
@OnlyIn(Dist.CLIENT)
AxisAlignedBB getVisualizationBounds(Level level, BlockPos pos);
AABB getVisualizationBounds(Level level, BlockPos pos);
@OnlyIn(Dist.CLIENT)
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.ModRegistry;
import de.ellpeck.naturesaura.reg.ModTileType;
import net.minecraft.block.*;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.Player;
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.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.FluidTags;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.entity.LivingEntity;
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.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.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 java.util.List;
import java.util.Random;
import java.util.function.Supplier;
public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
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);
this.baseName = baseName;
@ -46,7 +47,7 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
ModRegistry.add(this.tileType);
if (this.hasWaterlogging())
this.setDefaultState(this.stateContainer.getBaseState().with(BlockStateProperties.WATERLOGGED, false));
this.registerDefaultState(this.stateDefinition.any().setValue(BlockStateProperties.WATERLOGGED, false));
}
protected boolean hasWaterlogging() {
@ -54,37 +55,37 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
}
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
if (this.hasWaterlogging())
builder.add(BlockStateProperties.WATERLOGGED);
}
@Override
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
public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, ILevel levelIn, BlockPos currentPos, BlockPos facingPos) {
if (this.hasWaterlogging() && stateIn.get(BlockStateProperties.WATERLOGGED))
levelIn.getPendingFluidTicks().scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickRate(levelIn));
return super.updatePostPlacement(stateIn, facing, facingState, levelIn, currentPos, facingPos);
public BlockState updateShape(BlockState stateIn, Direction facing, BlockState facingState, LevelAccessor levelIn, BlockPos currentPos, BlockPos facingPos) {
if (this.hasWaterlogging() && stateIn.getValue(BlockStateProperties.WATERLOGGED))
levelIn.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(levelIn));
return super.updateShape(stateIn, facing, facingState, levelIn, currentPos, facingPos);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context) {
public BlockState getStateForPlacement(BlockPlaceContext context) {
if (this.hasWaterlogging()) {
FluidState state = context.getLevel().getFluidState(context.getPos());
return this.getDefaultState().with(BlockStateProperties.WATERLOGGED, state.isTagged(FluidTags.WATER) && state.getLevel() == 8);
FluidState state = context.getLevel().getFluidState(context.getClickedPos());
return this.defaultBlockState().setValue(BlockStateProperties.WATERLOGGED, state.is(FluidTags.WATER) && state.getAmount() == 8);
}
return super.getStateForPlacement(context);
}
@Nullable
@org.jetbrains.annotations.Nullable
@Override
public BlockEntity createNewBlockEntity(IBlockReader levelIn) {
return this.tileType.type.create();
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
return this.tileType.type.create(pos, state);
}
@Override
@ -93,20 +94,15 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
}
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.MODEL;
}
@Override
public void onPlayerDestroy(ILevel levelIn, BlockPos pos, BlockState state) {
super.onPlayerDestroy(levelIn, pos, state);
public RenderShape getRenderShape(BlockState state) {
return RenderShape.MODEL;
}
@Override
public List<ItemStack> getDrops(BlockState state, LootContext.Builder 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) {
for (ItemStack stack : drops) {
if (stack.getItem() != this.asItem())
@ -119,33 +115,28 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
}
@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()) {
BlockEntity tile = levelIn.getBlockEntity(pos);
if (tile instanceof BlockEntityImpl)
((BlockEntityImpl) tile).dropInventory();
}
super.onReplaced(state, levelIn, pos, newState, isMoving);
super.onPlace(state, levelIn, pos, newState, isMoving);
}
@Override
public void harvestBlock(Level levelIn, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack) {
super.harvestBlock(levelIn, player, pos, state, te, stack);
levelIn.setBlockState(pos, Blocks.AIR.getDefaultState());
public void playerDestroy(Level levelIn, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack) {
super.playerDestroy(levelIn, player, pos, state, te, stack);
levelIn.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState());
}
@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);
if (tile instanceof BlockEntityImpl)
((BlockEntityImpl) tile).loadDataOnPlace(stack);
}
@Override
public void onBlockAdded(BlockState state, Level levelIn, BlockPos pos, BlockState oldState, boolean isMoving) {
this.updateRedstoneState(levelIn, pos);
}
@Override
public void neighborChanged(BlockState state, Level levelIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) {
this.updateRedstoneState(levelIn, pos);
@ -154,11 +145,10 @@ public class BlockContainerImpl extends BaseEntityBlock implements IModItem {
private void updateRedstoneState(Level level, BlockPos pos) {
if (!level.isClientSide) {
BlockEntity tile = level.getBlockEntity(pos);
if (tile instanceof BlockEntityImpl) {
BlockEntityImpl impl = (BlockEntityImpl) tile;
int newPower = level.getRedstonePowerFromNeighbors(pos);
if (tile instanceof BlockEntityImpl impl) {
int newPower = level.getBestNeighborSignal(pos);
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) {
if (!levelIn.isClientSide) {
BlockEntity tile = levelIn.getBlockEntity(pos);
if (tile instanceof BlockEntityImpl) {
BlockEntityImpl impl = (BlockEntityImpl) tile;
int newPower = levelIn.getRedstonePowerFromNeighbors(pos);
if (tile instanceof BlockEntityImpl impl) {
int newPower = levelIn.getBestNeighborSignal(pos);
if (impl.redstonePower != newPower)
impl.onRedstonePowerChange(newPower);
}

View file

@ -2,49 +2,45 @@ package de.ellpeck.naturesaura.blocks;
import de.ellpeck.naturesaura.NaturesAura;
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.ModTileEntities;
import de.ellpeck.naturesaura.blocks.tiles.render.RenderEnderCrate;
import de.ellpeck.naturesaura.data.BlockStateGenerator;
import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.reg.ICustomBlockState;
import de.ellpeck.naturesaura.reg.ITESRProvider;
import net.minecraft.block.AnvilBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.tileentity.BlockEntityRenderer;
import net.minecraft.client.renderer.tileentity.BlockEntityRendererDispatcher;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.Player;
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.ChatFormatting;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.level.IBlockReader;
import net.minecraft.level.Level;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.TooltipFlag;
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.OnlyIn;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.AnvilUpdateEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.network.NetworkHooks;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
@ -52,11 +48,8 @@ import java.util.function.Supplier;
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() {
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);
}
@ -68,32 +61,22 @@ public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider
}
@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);
if (name != null && !name.isEmpty())
tooltip.add(new StringTextComponent(TextFormatting.DARK_PURPLE + I18n.format("info." + NaturesAura.MOD_ID + ".ender_name",
TextFormatting.ITALIC + name + TextFormatting.RESET)));
else
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));
if (name != null && !name.isEmpty()) {
tooltip.add(new TextComponent(ChatFormatting.DARK_PURPLE + I18n.get("info." + NaturesAura.MOD_ID + ".ender_name", ChatFormatting.ITALIC + name + ChatFormatting.RESET)));
} else {
tooltip.add(new TextComponent(ChatFormatting.DARK_PURPLE + I18n.get("info." + NaturesAura.MOD_ID + ".ender_name.missing")));
}
}
@SubscribeEvent
public void onAnvilUpdate(AnvilUpdateEvent event) {
WeakReference<Level> level = CACHED_WORLD.get();
if (level == null || level.get() == null)
var player = event.getPlayer();
if (player == null)
return;
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;
ItemStack second = event.getRight();
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();
if (name == null || name.isEmpty())
return;
if (ILevelData.getOverworldData(level.get()).isEnderStorageLocked(name))
if (ILevelData.getOverworldData(player.level).isEnderStorageLocked(name))
return;
ItemStack output = stack.copy();
output.getOrCreateTag().putString(NaturesAura.MOD_ID + ":ender_name", name);
@ -111,23 +94,20 @@ public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider
}
@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) {
BlockEntity tile = levelIn.getBlockEntity(pos);
if (tile instanceof BlockEntityEnderCrate) {
BlockEntityEnderCrate crate = (BlockEntityEnderCrate) tile;
if (crate.canOpen()) {
if (tile instanceof BlockEntityEnderCrate crate && crate.canOpen()) {
crate.drainAura(2500);
NetworkHooks.openGui((ServerPlayer) player, crate, pos);
}
}
}
return InteractionResult.SUCCESS;
}
@Override
@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);
}
@ -148,7 +128,7 @@ public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider
}
@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);
}

View file

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

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.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.tileentity.BlastFurnaceBlockEntity;
import net.minecraft.tileentity.ITickableBlockEntity;
import net.minecraft.tileentity.BlockEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.IIntArray;
import net.minecraft.util.math.BlockPos;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.inventory.ContainerData;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.level.block.entity.BlastFurnaceBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
@ -21,8 +21,8 @@ import java.util.List;
public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements ITickableBlockEntity {
public BlockEntityBlastFurnaceBooster() {
super(ModTileEntities.BLAST_FURNACE_BOOSTER);
public BlockEntityBlastFurnaceBooster(BlockPos pos, BlockState state) {
super(ModTileEntities.BLAST_FURNACE_BOOSTER, pos, state);
}
@Override
@ -30,34 +30,33 @@ public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements I
if (this.level.isClientSide)
return;
BlockEntity below = this.level.getBlockEntity(this.worldPosition.down());
if (!(below instanceof BlastFurnaceBlockEntity))
BlockEntity below = this.level.getBlockEntity(this.worldPosition.below());
if (!(below instanceof BlastFurnaceBlockEntity tile))
return;
BlastFurnaceBlockEntity tile = (BlastFurnaceBlockEntity) below;
IRecipe<?> recipe = this.level.getRecipeManager().getRecipe(BlockEntityFurnaceHeater.getRecipeType(tile), tile, this.level).orElse(null);
Recipe<?> recipe = this.level.getRecipeManager().getRecipeFor(BlockEntityFurnaceHeater.getRecipeType(tile), tile, this.level).orElse(null);
if (recipe == null)
return;
if (!this.isApplicable(recipe.getIngredients()))
return;
IIntArray data = BlockEntityFurnaceHeater.getFurnaceData(tile);
ContainerData data = BlockEntityFurnaceHeater.getFurnaceData(tile);
int doneDiff = data.get(3) - data.get(2);
if (doneDiff > 1)
return;
if (this.level.rand.nextFloat() > 0.45F) {
if (this.level.random.nextFloat() > 0.45F) {
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32,
new PacketParticles(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), PacketParticles.Type.BLAST_FURNACE_BOOSTER, 0));
return;
}
ItemStack output = tile.getStackInSlot(2);
ItemStack output = tile.getItem(2);
if (output.getCount() >= output.getMaxStackSize())
return;
if (output.isEmpty()) {
ItemStack result = recipe.getRecipeOutput();
tile.setInventorySlotContents(2, result.copy());
ItemStack result = recipe.getResultItem();
tile.setItem(2, result.copy());
} else {
output.grow(1);
}
@ -71,7 +70,7 @@ public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements I
private boolean isApplicable(List<Ingredient> 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/")))
return true;
}
@ -81,7 +80,7 @@ public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements I
@Override
public IItemHandlerModifiable getItemHandler() {
BlockEntity below = this.level.getBlockEntity(this.worldPosition.down());
BlockEntity below = this.level.getBlockEntity(this.worldPosition.below());
if (!(below instanceof BlastFurnaceBlockEntity))
return 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;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.tileentity.ITickableBlockEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.BlockPos;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import java.util.ArrayDeque;
import java.util.ArrayList;
@ -24,8 +22,8 @@ public class BlockEntityChorusGenerator extends BlockEntityImpl implements ITick
private final Deque<BlockPos> currentlyBreaking = new ArrayDeque<>();
private int auraPerBlock;
public BlockEntityChorusGenerator() {
super(ModTileEntities.CHORUS_GENERATOR);
public BlockEntityChorusGenerator(BlockPos pos, BlockState state) {
super(ModTileEntities.CHORUS_GENERATOR, pos, state);
}
@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()));
this.level.removeBlock(pos, false);
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);
}
@ -57,8 +55,8 @@ public class BlockEntityChorusGenerator extends BlockEntityImpl implements ITick
for (int x = -range; x <= range; x++) {
for (int y = -range; y <= range; y++) {
for (int z = -range; z <= range; z++) {
BlockPos offset = this.worldPosition.add(x, y, z);
BlockState below = this.level.getBlockState(offset.down());
BlockPos offset = this.worldPosition.offset(x, y, z);
BlockState below = this.level.getBlockState(offset.below());
if (below.getBlock() != Blocks.END_STONE)
continue;
BlockState state = this.level.getBlockState(offset);
@ -87,7 +85,7 @@ public class BlockEntityChorusGenerator extends BlockEntityImpl implements ITick
for (Direction dir : Direction.values()) {
if (dir == Direction.DOWN)
continue;
BlockPos offset = pos.offset(dir);
BlockPos offset = pos.relative(dir);
if (blocks.contains(offset))
continue;
BlockState state = this.level.getBlockState(offset);
@ -102,9 +100,9 @@ public class BlockEntityChorusGenerator extends BlockEntityImpl implements ITick
public void writeNBT(CompoundTag compound, SaveType type) {
super.writeNBT(compound, type);
if (type == SaveType.TILE) {
ListNBT list = new ListNBT();
ListTag list = new ListTag();
for (BlockPos pos : this.currentlyBreaking)
list.add(NBTUtil.writeBlockPos(pos));
list.add(NbtUtils.writeBlockPos(pos));
compound.put("breaking", list);
compound.putInt("aura", this.auraPerBlock);
}
@ -115,9 +113,9 @@ public class BlockEntityChorusGenerator extends BlockEntityImpl implements ITick
super.readNBT(compound, type);
if (type == SaveType.TILE) {
this.currentlyBreaking.clear();
ListNBT list = compound.getList("breaking", 10);
ListTag list = compound.getList("breaking", 10);
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");
}
}

View file

@ -2,12 +2,12 @@ package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.ModConfig;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.tileentity.ITickableBlockEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.Mth;
import net.minecraft.level.server.ServerLevel;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.block.state.BlockState;
import java.util.ArrayList;
import java.util.Arrays;
@ -19,13 +19,13 @@ public class BlockEntityChunkLoader extends BlockEntityImpl implements ITickable
private final List<ChunkPos> forcedChunks = new ArrayList<>();
private boolean firstTick = true;
public BlockEntityChunkLoader() {
super(ModTileEntities.CHUNK_LOADER);
public BlockEntityChunkLoader(BlockPos pos, BlockState state) {
super(ModTileEntities.CHUNK_LOADER, pos, state);
}
@Override
public void remove() {
super.remove();
public void setRemoved() {
super.setRemoved();
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++) {
ChunkPos pos = new ChunkPos(x, z);
// 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);
}
}
}
}
// 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) {
if (!shouldBeForced.contains(pos))
level.forceChunk(pos.x, pos.z, false);
level.setChunkForced(pos.x, pos.z, false);
}
this.forcedChunks.clear();
// Force all chunks that should be forced
for (ChunkPos pos : shouldBeForced) {
level.forceChunk(pos.x, pos.z, true);
level.setChunkForced(pos.x, pos.z, true);
this.forcedChunks.add(pos);
}
}
@ -100,7 +100,7 @@ public class BlockEntityChunkLoader extends BlockEntityImpl implements ITickable
public void writeNBT(CompoundTag compound, SaveType type) {
super.writeNBT(compound, type);
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

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;
import net.minecraft.item.ItemStack;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.ItemStackHandler;
import javax.annotation.Nonnull;
@ -23,7 +23,7 @@ public class ItemStackHandlerNA extends ItemStackHandler {
@Override
protected void onContentsChanged(int slot) {
if (this.tile != null) {
this.tile.markDirty();
this.tile.setChanged();
if (this.sendToClients && !this.tile.getLevel().isClientSide)
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.gui.ContainerEnderCrate;
import de.ellpeck.naturesaura.gui.ModContainers;
import net.minecraft.core.BlockPos;
import net.minecraft.entity.player.Player;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting;
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 javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class BlockEntityEnderCrate extends BlockEntityImpl implements INamedContainerProvider {
public class BlockEntityEnderCrate extends BlockEntityImpl implements MenuProvider {
public String name;
private final IItemHandlerModifiable wrappedEnderStorage = new IItemHandlerModifiable() {
@ -74,8 +79,8 @@ public class BlockEntityEnderCrate extends BlockEntityImpl implements INamedCont
}
};
public BlockEntityEnderCrate() {
super(ModTileEntities.ENDER_CRATE);
public BlockEntityEnderCrate(BlockPos pos, BlockState state) {
super(ModTileEntities.ENDER_CRATE, pos, state);
}
@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;
import com.google.common.collect.ImmutableList;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Matrix4f;
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.tileentity.BlockEntityRenderer;
import net.minecraft.client.renderer.tileentity.BlockEntityRendererDispatcher;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;
@OnlyIn(Dist.CLIENT)
public class RenderEnderCrate extends 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);
}
public class RenderEnderCrate implements BlockEntityRenderer<BlockEntityEnderCrate> {
@Override
public void render(BlockEntityEnderCrate tileEntityIn, float partialTicks, MatrixStack matrixStackIn, IRenderTypeBuffer bufferIn, int combinedLightIn, int combinedOverlayIn) {
RANDOM.setSeed(31100L);
double d0 = tileEntityIn.getPos().distanceSq(this.renderDispatcher.renderInfo.getProjectedView(), true);
int i = this.getPasses(d0);
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)));
}
public void render(BlockEntityEnderCrate tileEntityIn, float partialTicks, PoseStack matrixStackIn, MultiBufferSource bufferIn, int combinedLightIn, int combinedOverlayIn) {
Matrix4f matrix4f = matrixStackIn.last().pose();
float f1 = RenderEnderCrate.getOffsetUp();
RenderEnderCrate.renderFace(matrix4f, bufferIn.getBuffer(RenderEnderCrate.renderType()), f1, f1);
}
private void renderCube(float g, float h, Matrix4f mat, IVertexBuilder builder) {
float f = (RANDOM.nextFloat() * 0.5F + 0.1F) * h;
float f1 = (RANDOM.nextFloat() * 0.5F + 0.4F) * h;
float f2 = (RANDOM.nextFloat() * 0.5F + 0.5F) * h;
this.renderFace(mat, builder, g, g, f, f1, f2);
private static void renderFace(Matrix4f p_173696_, VertexConsumer p_173697_, float p_173700_, float p_173701_) {
p_173697_.vertex(p_173696_, (float) 0.0, p_173700_, (float) 1.0).endVertex();
p_173697_.vertex(p_173696_, (float) 1.0, p_173700_, (float) 1.0).endVertex();
p_173697_.vertex(p_173696_, (float) 1.0, p_173701_, (float) 0.0).endVertex();
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) {
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() {
private static float getOffsetUp() {
return 1.001F;
}
private static RenderType renderType() {
return RenderType.endPortal();
}
}

View file

@ -1,6 +1,5 @@
package de.ellpeck.naturesaura.entities;
import com.google.common.collect.ListMultimap;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
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.ModItems;
import de.ellpeck.naturesaura.misc.LevelData;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.item.ItemStack;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.IPacket;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EntityDamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.level.Level;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.EntityDamageSource;
import net.minecraft.world.entity.Entity;
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.OnlyIn;
import net.minecraftforge.fml.network.NetworkHooks;
import java.util.List;
import net.minecraftforge.network.NetworkHooks;
public class EntityEffectInhibitor extends Entity implements IVisualizable {
private static final DataParameter<String> INHIBITED_EFFECT = EntityDataManager.createKey(EntityEffectInhibitor.class, DataSerializers.STRING);
private static final DataParameter<Integer> COLOR = EntityDataManager.createKey(EntityEffectInhibitor.class, DataSerializers.VARINT);
private static final DataParameter<Integer> AMOUNT = EntityDataManager.createKey(EntityEffectInhibitor.class, DataSerializers.VARINT);
private static final EntityDataAccessor<String> INHIBITED_EFFECT = SynchedEntityData.defineId(EntityEffectInhibitor.class, EntityDataSerializers.STRING);
private static final EntityDataAccessor<Integer> COLOR = SynchedEntityData.defineId(EntityEffectInhibitor.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Integer> AMOUNT = SynchedEntityData.defineId(EntityEffectInhibitor.class, EntityDataSerializers.INT);
private ResourceLocation lastEffect;
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) {
ResourceLocation effect = ItemEffectPowder.getEffect(stack);
EntityEffectInhibitor entity = new EntityEffectInhibitor(ModEntities.EFFECT_INHIBITOR, level);
var effect = ItemEffectPowder.getEffect(stack);
var entity = new EntityEffectInhibitor(ModEntities.EFFECT_INHIBITOR, level);
entity.setInhibitedEffect(effect);
entity.setColor(NaturesAuraAPI.EFFECT_POWDERS.get(effect));
entity.setAmount(stack.getCount());
entity.setPosition(posX, posY, posZ);
level.addEntity(entity);
entity.setPos(posX, posY, posZ);
level.addFreshEntity(entity);
}
@Override
public void onAddedToLevel() {
super.onAddedToLevel();
public void onAddedToWorld() {
super.onAddedToWorld();
this.powderListDirty = true;
}
@Override
public void onRemovedFromLevel() {
super.onRemovedFromLevel();
public void onRemovedFromWorld() {
super.onRemovedFromWorld();
this.setInhibitedEffect(null);
this.updatePowderListStatus();
}
@Override
protected void registerData() {
this.dataManager.register(INHIBITED_EFFECT, null);
this.dataManager.register(COLOR, 0);
this.dataManager.register(AMOUNT, 0);
protected void defineSynchedData() {
this.entityData.define(INHIBITED_EFFECT, null);
this.entityData.define(COLOR, 0);
this.entityData.define(AMOUNT, 0);
}
@Override
public void notifyDataManagerChange(DataParameter<?> key) {
super.notifyDataManagerChange(key);
public void onSyncedDataUpdated(EntityDataAccessor<?> key) {
super.onSyncedDataUpdated(key);
if (INHIBITED_EFFECT.equals(key) || AMOUNT.equals(key))
this.powderListDirty = true;
}
@Override
public void setPosition(double x, double y, double z) {
if (x != this.getPosX() || y != this.getPosY() || z != this.getPosZ())
public void setPos(double x, double y, double z) {
if (x != this.getX() || y != this.getY() || z != this.getZ())
this.powderListDirty = true;
super.setPosition(x, y, z);
super.setPos(x, y, z);
}
@Override
@ -99,13 +95,13 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
if (this.level.isClientSide) {
if (this.level.getGameTime() % 5 == 0) {
NaturesAuraAPI.instance().spawnMagicParticle(
this.getPosX() + this.level.rand.nextGaussian() * 0.1F,
this.getPosY(),
this.getPosZ() + this.level.rand.nextGaussian() * 0.1F,
this.level.rand.nextGaussian() * 0.005F,
this.level.rand.nextFloat() * 0.03F,
this.level.rand.nextGaussian() * 0.005F,
this.getColor(), this.level.rand.nextFloat() * 3F + 1F, 120, 0F, true, true);
this.getX() + this.level.random.nextGaussian() * 0.1F,
this.getY(),
this.getZ() + this.level.random.nextGaussian() * 0.1F,
this.level.random.nextGaussian() * 0.005F,
this.level.random.nextFloat() * 0.03F,
this.level.random.nextGaussian() * 0.005F,
this.getColor(), this.level.random.nextFloat() * 3F + 1F, 120, 0F, true, true);
}
this.renderTicks++;
}
@ -117,32 +113,32 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
}
@Override
protected void readAdditional(CompoundTag compound) {
protected void readAdditionalSaveData(CompoundTag compound) {
this.setInhibitedEffect(new ResourceLocation(compound.getString("effect")));
this.setColor(compound.getInt("color"));
this.setAmount(compound.contains("amount") ? compound.getInt("amount") : 24);
}
@Override
protected void writeAdditional(CompoundTag compound) {
protected void addAdditionalSaveData(CompoundTag compound) {
compound.putString("effect", this.getInhibitedEffect().toString());
compound.putInt("color", this.getColor());
compound.putInt("amount", this.getAmount());
}
@Override
public IPacket<?> createSpawnPacket() {
public Packet<?> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
public boolean attackEntityFrom(DamageSource source, float amount) {
public boolean hurt(DamageSource source, float amount) {
if (source instanceof EntityDamageSource && !this.level.isClientSide) {
this.remove();
this.entityDropItem(this.getDrop(), 0F);
this.kill();
this.spawnAtLocation(this.getDrop(), 0F);
return true;
} else
return super.attackEntityFrom(source, amount);
return super.hurt(source, amount);
}
public ItemStack getDrop() {
@ -150,36 +146,36 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
}
public ResourceLocation getInhibitedEffect() {
String effect = this.dataManager.get(INHIBITED_EFFECT);
var effect = this.entityData.get(INHIBITED_EFFECT);
if (effect == null || effect.isEmpty())
return null;
return new 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() {
return this.dataManager.get(COLOR);
return this.entityData.get(COLOR);
}
public void setColor(int color) {
this.dataManager.set(COLOR, color);
this.entityData.set(COLOR, color);
}
public int getAmount() {
return this.dataManager.get(AMOUNT);
return this.entityData.get(AMOUNT);
}
public void setAmount(int amount) {
this.dataManager.set(AMOUNT, amount);
this.entityData.set(AMOUNT, amount);
}
@Override
@OnlyIn(Dist.CLIENT)
public AxisAlignedBB getVisualizationBounds(Level level, BlockPos pos) {
return Helper.aabb(this.getPositionVec()).grow(this.getAmount());
public AABB getVisualizationBounds(Level level, BlockPos pos) {
return Helper.aabb(this.getEyePosition()).inflate(this.getAmount());
}
@Override
@ -189,15 +185,15 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
}
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) {
List<Tuple<Vector3d, Integer>> oldList = powders.get(this.lastEffect);
oldList.removeIf(t -> this.getPositionVec().equals(t.getA()));
var oldList = powders.get(this.lastEffect);
oldList.removeIf(t -> this.getEyePosition().equals(t.getA()));
}
ResourceLocation effect = this.getInhibitedEffect();
var effect = this.getInhibitedEffect();
if (effect != null) {
List<Tuple<Vector3d, Integer>> newList = powders.get(effect);
newList.add(new Tuple<>(this.getPositionVec(), this.getAmount()));
var newList = powders.get(effect);
newList.add(new Tuple<>(this.getEyePosition(), this.getAmount()));
}
this.powderListDirty = false;
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.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.block.BlockState;
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.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.INBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.LongNBT;
import net.minecraft.network.IPacket;
import net.minecraft.util.DamageSource;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Mth;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.level.GameRules;
import net.minecraft.level.Level;
import net.minecraft.level.server.ServerLevel;
import net.minecraftforge.common.util.Constants;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.LongTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameRules;
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.fml.network.NetworkHooks;
import net.minecraftforge.network.NetworkHooks;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class EntityMoverMinecart extends AbstractMinecartEntity {
public class EntityMoverMinecart extends AbstractMinecart {
private final List<BlockPos> spotOffsets = new ArrayList<>();
public boolean isActive;
@ -50,14 +49,14 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
super.moveMinecartOnRail(railPos);
if (!this.isActive)
return;
BlockPos pos = this.getPosition();
BlockPos pos = this.getOnPos();
if (!this.spotOffsets.isEmpty() && this.level.getGameTime() % 10 == 0)
PacketHandler.sendToAllAround(this.level, pos, 32, new PacketParticles(
(float) this.getPosX(), (float) this.getPosY(), (float) this.getPosZ(), PacketParticles.Type.MOVER_CART,
Mth.floor(this.getMotion().getX() * 100F), Mth.floor(this.getMotion().getY() * 100F), Mth.floor(this.getMotion().getZ() * 100F)));
(float) this.getX(), (float) this.getY(), (float) this.getZ(), PacketParticles.Type.MOVER_CART,
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;
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) {
for (BlockPos offset : this.spotOffsets) {
BlockPos spot = oldPos.add(offset);
BlockPos spot = oldPos.offset(offset);
IAuraChunk chunk = IAuraChunk.getAuraChunk(oldLevel, spot);
int amount = chunk.getDrainSpot(spot);
if (amount <= 0)
@ -76,17 +75,17 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
if (drained <= 0)
continue;
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);
}
}
@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) {
this.isActive = receivingPower;
BlockPos pos = this.getPosition();
BlockPos pos = this.getOnPos();
if (!this.isActive) {
this.moveAura(this.level, this.lastPosition, this.level, pos);
this.spotOffsets.clear();
@ -103,21 +102,21 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
}
@Override
public void killMinecart(DamageSource source) {
this.remove();
if (this.level.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS))
this.entityDropItem(new ItemStack(ModItems.MOVER_CART), 0);
public void destroy(DamageSource source) {
this.kill();
if (this.level.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS))
this.spawnAtLocation(new ItemStack(ModItems.MOVER_CART), 0);
}
@Override
public CompoundTag serializeNBT() {
CompoundTag compound = super.serializeNBT();
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)
list.add(LongNBT.valueOf(offset.toLong()));
list.add(LongTag.valueOf(offset.asLong()));
compound.put("offsets", list);
return compound;
}
@ -126,12 +125,12 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
public void deserializeNBT(CompoundTag compound) {
super.deserializeNBT(compound);
this.isActive = compound.getBoolean("active");
this.lastPosition = BlockPos.fromLong(compound.getLong("last_pos"));
this.lastPosition = BlockPos.of(compound.getLong("last_pos"));
this.spotOffsets.clear();
ListNBT list = compound.getList("offsets", Constants.NBT.TAG_LONG);
for (INBT base : list)
this.spotOffsets.add(BlockPos.fromLong(((LongNBT) base).getLong()));
ListTag list = compound.getList("offsets", Tag.TAG_LONG);
for (Tag base : list)
this.spotOffsets.add(BlockPos.of(((LongTag) base).getAsLong()));
}
@Nullable
@ -139,7 +138,7 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
public Entity changeDimension(ServerLevel destination, ITeleporter teleporter) {
Entity entity = super.changeDimension(destination, teleporter);
if (entity instanceof EntityMoverMinecart) {
BlockPos pos = entity.getPosition();
BlockPos pos = entity.getOnPos();
this.moveAura(this.level, this.lastPosition, entity.level, pos);
((EntityMoverMinecart) entity).lastPosition = pos;
}
@ -147,8 +146,8 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
}
@Override
public BlockState getDisplayTile() {
return Blocks.STONE.getDefaultState();
public BlockState getDisplayBlockState() {
return Blocks.STONE.defaultBlockState();
}
@Override
@ -162,7 +161,7 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
}
@Override
public ItemStack getPickedResult(RayTraceResult target) {
public ItemStack getPickedResult(HitResult target) {
return new ItemStack(ModItems.MOVER_CART);
}
@ -172,13 +171,13 @@ public class EntityMoverMinecart extends AbstractMinecartEntity {
}
@Override
protected void applyDrag() {
Vector3d motion = this.getMotion();
this.setMotion(motion.x * 0.99F, 0, motion.z * 0.99F);
protected void applyNaturalSlowdown() {
Vec3 motion = this.getDeltaMovement();
this.setDeltaMovement(motion.x * 0.99F, 0, motion.z * 0.99F);
}
@Override
public IPacket<?> createSpawnPacket() {
public Packet<?> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
}

View file

@ -1,9 +1,10 @@
package de.ellpeck.naturesaura.entities;
import net.minecraft.entity.EntityType;
import net.minecraft.world.entity.EntityType;
@SuppressWarnings("FieldNamingConvention")
public final class ModEntities {
public static EntityType<EntityMoverMinecart> MOVER_CART;
public static EntityType<EntityEffectInhibitor> EFFECT_INHIBITOR;
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.client.renderer.color.IItemColor;
import net.minecraft.entity.player.Player;
import net.minecraft.item.DyeColor;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
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.OnlyIn;

View file

@ -3,17 +3,17 @@ package de.ellpeck.naturesaura.items;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.entities.EntityEffectInhibitor;
import de.ellpeck.naturesaura.reg.IColorProvidingItem;
import net.minecraft.client.renderer.color.IItemColor;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.util.InteractionResult;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.level.Level;
import net.minecraft.client.color.item.ItemColor;
import net.minecraft.core.NonNullList;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@ -38,11 +38,11 @@ public class ItemEffectPowder extends ItemImpl implements IColorProvidingItem {
}
@Override
public InteractionResult onItemUse(ItemUseContext context) {
public InteractionResult useOn(UseOnContext context) {
Level level = context.getLevel();
if (!level.isClientSide) {
Vector3d hit = context.getHitVec();
ItemStack stack = context.getPlayer().getHeldItem(context.getHand());
Vec3 hit = context.getClickLocation();
ItemStack stack = context.getPlayer().getItemInHand(context.getHand());
EntityEffectInhibitor.place(level, stack, hit.x, hit.y + 1, hit.z);
stack.setCount(0);
}
@ -50,8 +50,8 @@ public class ItemEffectPowder extends ItemImpl implements IColorProvidingItem {
}
@Override
public void fillItemGroup(ItemGroup tab, NonNullList<ItemStack> items) {
if (this.isInGroup(tab)) {
public void fillItemCategory(CreativeModeTab tab, NonNullList<ItemStack> items) {
if (this.allowdedIn(tab)) {
for (ResourceLocation effect : NaturesAuraAPI.EFFECT_POWDERS.keySet()) {
ItemStack stack = new ItemStack(this);
setEffect(stack, effect);
@ -61,13 +61,13 @@ public class ItemEffectPowder extends ItemImpl implements IColorProvidingItem {
}
@Override
public ITextComponent getDisplayName(ItemStack stack) {
return new TranslationTextComponent(this.getTranslationKey(stack) + "." + getEffect(stack));
public Component getName(ItemStack stack) {
return new TranslatableComponent(this.getDescriptionId(stack) + "." + getEffect(stack));
}
@Override
@OnlyIn(Dist.CLIENT)
public IItemColor getItemColor() {
public ItemColor getItemColor() {
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 de.ellpeck.naturesaura.NaturesAura;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.particle.IParticleRenderType;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.level.ClientLevel;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
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.renderers.PlayerLayerTrinkets;
import de.ellpeck.naturesaura.renderers.SupporterFancyHandler;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScreenManager;
import net.minecraft.client.renderer.RenderTypeLookup;
import net.minecraft.client.renderer.color.IItemColor;
import net.minecraft.client.renderer.color.ItemColors;
import net.minecraft.client.renderer.entity.PlayerRenderer;
import net.minecraft.client.renderer.tileentity.BlockEntityRenderer;
import net.minecraft.client.renderer.tileentity.BlockEntityRendererDispatcher;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.item.Item;
import net.minecraft.item.ItemModelsProperties;
import net.minecraft.tileentity.BlockEntity;
import net.minecraft.tileentity.BlockEntityType;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Tuple;
import net.minecraft.client.color.item.ItemColor;
import net.minecraft.client.color.item.ItemColors;
import net.minecraft.client.gui.screens.MenuScreens;
import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderers;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.EntityRenderers;
import net.minecraft.client.renderer.entity.player.PlayerRenderer;
import net.minecraft.client.renderer.item.ItemProperties;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
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 java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
public class ClientProxy implements IProxy {
@ -45,20 +39,22 @@ public class ClientProxy implements IProxy {
public void preInit(FMLCommonSetupEvent event) {
MinecraftForge.EVENT_BUS.register(new ClientEvents());
Compat.setupClient();
ScreenManager.registerFactory(ModContainers.ENDER_CRATE, GuiEnderCrate::new);
ScreenManager.registerFactory(ModContainers.ENDER_ACCESS, GuiEnderCrate::new);
MenuScreens.register(ModContainers.ENDER_CRATE, 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);
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);
}
@Override
public void init(FMLCommonSetupEvent event) {
Map<String, PlayerRenderer> skinMap = Minecraft.getInstance().getRenderManager().getSkinMap();
for (PlayerRenderer render : new PlayerRenderer[]{skinMap.get("default"), skinMap.get("slim")})
render.addLayer(new PlayerLayerTrinkets(render));
var skinMap = Minecraft.getInstance().getEntityRenderDispatcher().getSkinMap();
for (var render : new EntityRenderer[]{skinMap.get("default"), skinMap.get("slim")}) {
if (render instanceof PlayerRenderer living)
living.addLayer(new PlayerLayerTrinkets(living));
}
new SupporterFancyHandler();
}
@ -66,14 +62,14 @@ public class ClientProxy implements IProxy {
public void postInit(FMLCommonSetupEvent event) {
for (IModItem item : ModRegistry.ALL_ITEMS) {
if (item instanceof ICustomRenderType)
RenderTypeLookup.setRenderLayer((Block) item, ((ICustomRenderType) item).getRenderType().get());
ItemBlockRenderTypes.setRenderLayer((Block) item, ((ICustomRenderType) item).getRenderType().get());
}
}
@Override
public void addColorProvidingItem(IColorProvidingItem item) {
ItemColors colors = Minecraft.getInstance().getItemColors();
IItemColor color = item.getItemColor();
ItemColor color = item.getItemColor();
if (item instanceof Item) {
colors.register(color, (Item) item);
@ -84,15 +80,14 @@ public class ClientProxy implements IProxy {
@Override
public void addColorProvidingBlock(IColorProvidingBlock block) {
if (block instanceof Block) {
if (block instanceof Block)
Minecraft.getInstance().getBlockColors().register(block.getBlockColor(), (Block) block);
}
}
@Override
public void registerTESR(ITESRProvider provider) {
Tuple<BlockEntityType<BlockEntity>, Supplier<Function<? super BlockEntityRendererDispatcher, ? extends BlockEntityRenderer<? super BlockEntity>>>> tesr = provider.getTESR();
ClientRegistry.bindBlockEntityRenderer(tesr.getA(), tesr.getB().get());
public void registerTESR(ITESRProvider<?> provider) {
var tesr = provider.getTESR();
BlockEntityRenderers.register(tesr.getA(), tesr.getB().get());
}
@Override
@ -119,8 +114,8 @@ public class ClientProxy implements IProxy {
}
@Override
public <T extends Entity> void registerEntityRenderer(EntityType<T> entityClass, Supplier<IRenderFactory<T>> renderFactory) {
RenderingRegistry.registerEntityRenderingHandler(entityClass, renderFactory.get());
public <T extends Entity> void registerEntityRenderer(EntityType<T> entityClass, Supplier<EntityRendererProvider<T>> renderFactory) {
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.IColorProvidingItem;
import de.ellpeck.naturesaura.reg.ITESRProvider;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraftforge.fml.client.registry.IRenderFactory;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import java.util.function.Supplier;
public interface IProxy {
void preInit(FMLCommonSetupEvent event);
void init(FMLCommonSetupEvent event);
@ -21,7 +22,7 @@ public interface IProxy {
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);
@ -31,6 +32,5 @@ public interface IProxy {
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;
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.OnlyIn;
public interface IColorProvidingBlock {
@OnlyIn(Dist.CLIENT)
IBlockColor getBlockColor();
BlockColor getBlockColor();
}

View file

@ -1,19 +1,17 @@
package de.ellpeck.naturesaura.reg;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.util.Tuple;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import java.util.function.Function;
import java.util.function.Supplier;
public interface ITESRProvider<T extends BlockEntity> {
@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;
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.api.render.ITrinketItem;
import de.ellpeck.naturesaura.api.render.ITrinketItem.RenderType;
import de.ellpeck.naturesaura.compat.Compat;
import net.minecraft.client.entity.player.AbstractClientPlayer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.entity.IEntityRenderer;
import net.minecraft.client.renderer.entity.layers.LayerRenderer;
import net.minecraft.client.renderer.entity.model.PlayerModel;
import net.minecraft.entity.Pose;
import net.minecraft.entity.player.Player;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.Effects;
import net.minecraft.util.math.vector.Vector3f;
import net.minecraft.client.model.PlayerModel;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.RenderLayerParent;
import net.minecraft.client.renderer.entity.layers.RenderLayer;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.IItemHandler;
import top.theillusivec4.curios.api.CuriosApi;
import java.util.HashSet;
import java.util.Set;
@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<>();
public PlayerLayerTrinkets(IEntityRenderer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>> entityRendererIn) {
super(entityRendererIn);
public PlayerLayerTrinkets(RenderLayerParent<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>> p_117346_) {
super(p_117346_);
}
@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())
return;
if (player.getActivePotionEffect(Effects.INVISIBILITY) != null)
if (player.getEffect(MobEffects.INVISIBILITY) != null)
return;
ItemStack main = player.getHeldItemMainhand();
ItemStack second = player.getHeldItemOffhand();
var main = player.getMainHandItem();
var second = player.getOffhandItem();
this.alreadyRendered.clear();
matrixStackIn.push();
matrixStackIn.pushPose();
this.render(player, RenderType.BODY, main, second, matrixStackIn, bufferIn, packedLightIn);
float yaw = player.prevRotationYawHead + (player.rotationYawHead - player.prevRotationYawHead) * partialTicks;
float yawOffset = player.prevRenderYawOffset + (player.renderYawOffset - player.prevRenderYawOffset) * partialTicks;
float pitch = player.prevRotationPitch + (player.rotationPitch - player.prevRotationPitch) * partialTicks;
matrixStackIn.rotate(Vector3f.YN.rotationDegrees(yawOffset));
matrixStackIn.rotate(Vector3f.YP.rotationDegrees(yaw - 270));
matrixStackIn.rotate(Vector3f.ZP.rotationDegrees(pitch));
var yaw = player.yHeadRotO + (player.yHeadRot - player.yHeadRotO) * partialTicks;
var yawOffset = player.yBodyRotO + (player.yBodyRot - player.yBodyRotO) * partialTicks;
var pitch = player.xRotO + (player.getXRot() - player.xRotO) * partialTicks;
matrixStackIn.mulPose(Vector3f.YN.rotationDegrees(yawOffset));
matrixStackIn.mulPose(Vector3f.YP.rotationDegrees(yaw - 270));
matrixStackIn.mulPose(Vector3f.ZP.rotationDegrees(pitch));
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) {
for (int i = 0; i < player.inventory.getSizeInventory(); i++) {
this.renderStack(player.inventory.getStackInSlot(i), player, type, main, second, matrices, buffer, packedLight);
private void render(Player player, RenderType type, ItemStack main, ItemStack second, PoseStack matrices, MultiBufferSource buffer, int packedLight) {
for (var i = 0; i < player.getInventory().getContainerSize(); i++) {
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);
if (handler != null) {
for (int i = 0; i < handler.getSlots(); i++)
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()) {
Item item = stack.getItem();
var item = stack.getItem();
if (item instanceof ITrinketItem && !this.alreadyRendered.contains(item)) {
matrices.push();
matrices.pushPose();
if (type == RenderType.BODY && player.getPose() == Pose.CROUCHING) {
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);
matrices.pop();
matrices.popPose();
this.alreadyRendered.add(item);
}
}