Jump to content

[Solved] [1.19.4] Changing block entity data from block entity renderer


PRYtheSheep

Recommended Posts

Hi, I am trying to modify a block entity's variable from its block entity renderer class. The variable facing is direction of the entity in degrees. The renderer class access the variable facing and rotates it to face towards the entity it is tracking. However, the changes are not reflected in the block entity class. Printing out entity.facing to console in the block entity renderer class displays the correct output in degrees but printing out facing in the block entity class shows it is stuck at -1.

I figure it might be something to do with renderers being client side, if so, could someone point me in the right direction? Thanks

 

Block Entity 

Spoiler
package net.mod.prymod.ModBlock;

import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.targeting.TargetingConditions;
import net.minecraft.world.entity.ambient.Bat;
import net.minecraft.world.entity.animal.Animal;
import net.minecraft.world.entity.animal.Fox;
import net.minecraft.world.entity.animal.Pig;
import net.minecraft.world.entity.monster.Phantom;
import net.minecraft.world.entity.player.Player;
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.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.mod.prymod.itemMod.custom.ProximityArrowEntity;
import software.bernie.example.entity.BatEntity;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;

public class PRYBlockEntity extends BlockEntity {

    int progress = 0;
    public float facing = 0;
    public PRYBlockEntity(BlockPos pos, BlockState state) {
        super(ModBlockEntityInit.PRYBLOCKENTITY.get(), pos, state);
    }

    public static Entity target = null;
    public static boolean pointingAtTarget = false;
    public void tick() {

        /*Predicate<Entity> predicate = (i) -> (i instanceof Player);
        Player player = this.level.getNearestPlayer(this.getBlockPos().getX(), this.getBlockPos().getY(), this.getBlockPos().getZ(), 3, predicate);
        if(player != null){
            player.displayClientMessage(Component.literal("player near"), false);
        }*/
        AABB startEndBox = new AABB(
                this.getBlockPos().getX()-90,
                this.getBlockPos().getY(),
                this.getBlockPos().getZ()-90,
                this.getBlockPos().getX()+90,
                this.getBlockPos().getY()+90,
                this.getBlockPos().getZ()+90);


        Predicate<Entity> predicate = (i) -> (i instanceof Player);
        List<Entity> list1 = this.level.getEntities(null, startEndBox);


        if(progress % 50 == 0){
            //Progress = 0;
            Player player = this.level.getNearestPlayer(this.getBlockPos().getX(), this.getBlockPos().getY(), this.getBlockPos().getZ(), 10000, predicate);


            for(Entity entity : list1){
                if(entity instanceof Bat && ((Bat) entity).getHealth() != 0) {
                    target = entity;
                    ProximityArrowEntity proxyArrow = new ProximityArrowEntity(ModBlockEntityInit.PROXIMITY_ARROW_ENTITY.get(), this.level);
                    proxyArrow.setPos(this.getBlockPos().getX() + 0.5, this.getBlockPos().getY() + 1.2, this.getBlockPos().getZ() + 0.5);
                    Vec3 resultantVector = new Vec3((entity.getX() - this.getBlockPos().getX()),
                                                    (entity.getY() - this.getBlockPos().getY()),
                                                    (entity.getZ() - this.getBlockPos().getZ()));
                    if(!ProximityArrowEntity.inFlight && ProximityArrowEntity.target == null && pointingAtTarget){
                        proxyArrow.setDeltaMovement(resultantVector);
                        if(proxyArrow.getDeltaMovement().length() > 0.1){
                            proxyArrow.setDeltaMovement(proxyArrow.getDeltaMovement().multiply(
                                    1/proxyArrow.getDeltaMovement().length(),
                                    1/proxyArrow.getDeltaMovement().length(),
                                    1/proxyArrow.getDeltaMovement().length()
                            ));
                        }
                        this.level.addFreshEntity(proxyArrow);
                        ProximityArrowEntity.target = entity;
                        ProximityArrowEntity.inFlight = true;
                        if(player != null){
                            player.displayClientMessage(Component.literal("§aMissile launched"), true);
                        }
                    }
                    break;
                }
            }
        }
        if(target == null){
            ProximityArrowEntity.target = null;
            ProximityArrowEntity.inFlight = false;
        }
        progress++;
    }

    @Override
    protected void saveAdditional(CompoundTag nbt) {
        super.saveAdditional(nbt);
        nbt.putInt("progress", this.progress);
        nbt.putFloat("facing", this.facing);
    }

    @Override
    public void load(CompoundTag nbt) {
        super.load(nbt);
        this.progress = nbt.getInt("progress");
        this.facing = nbt.getFloat("facing");
    }
}

 

Block entity renderer

Spoiler
package net.mod.prymod.Renderer;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import com.sun.jna.platform.win32.OaIdl;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.Direction;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.Tags;
import net.mod.prymod.ModBlock.ModBlock;
import net.mod.prymod.ModBlock.PRYBlock;
import net.mod.prymod.ModBlock.PRYBlockEntity;
import net.mod.prymod.itemMod.custom.ProximityArrowEntity;
import software.bernie.shadowed.eliotlash.mclib.math.functions.limit.Min;


public class PRYBlockEntityRenderer implements BlockEntityRenderer<PRYBlockEntity> {

    BlockEntityRendererProvider.Context context;

    public PRYBlockEntityRenderer(BlockEntityRendererProvider.Context context){
        this.context = context;
    }


    @Override
    public void render(PRYBlockEntity entity, float partialTick, PoseStack stack, MultiBufferSource buffer, int packedLight, int packedOverlay) {
        System.out.println("facing is " + entity.facing);
        final BlockRenderDispatcher blockRenderDispatcher = this.context.getBlockRenderDispatcher();


        Vec3 targetPos = null;

        switch(entity.getBlockState().getValue(PRYBlock.FACING)){
            case NORTH -> {
                stack.translate(0, 0, 0.15);
            }
            case EAST -> {
                stack.translate(-0.15, 0, 0);
            }
            case SOUTH -> {
                stack.translate(0, 0, -0.15);
            }
            case WEST -> {
                stack.translate(0.15, 0, 0);
            }
        }
        if(entity.facing == -1){
            switch(entity.getBlockState().getValue(PRYBlock.FACING)){
                case NORTH -> {
                    entity.facing = 0;
                }
                case EAST -> {
                    entity.facing = 90;
                }
                case SOUTH -> {
                    entity.facing = 180;
                }
                case WEST -> {
                    entity.facing = 270;
                }
            }
        }
        entity.setChanged();

        if (PRYBlockEntity.target != null) {
            targetPos = PRYBlockEntity.target.getEyePosition();
        }
        else{
            entity.pointingAtTarget = false;
            float defaultAngle = 0;

            switch(entity.getBlockState().getValue(PRYBlock.FACING)){
                case NORTH -> {
                    defaultAngle = 0;
                }
                case EAST -> {
                    defaultAngle = 90;
                }
                case SOUTH -> {
                    defaultAngle = 180;
                }
                case WEST -> {
                    defaultAngle = 270;
                }
            }

            Vec3 facingVector = getVectorForRotation(0, entity.facing);
            Vec3 angleVector = getVectorForRotation(0, defaultAngle);
            Vec3 crossVector = facingVector.cross(angleVector);

            float angleBetween = angleBetween2Vectors(facingVector, angleVector);
            if(angleBetween > 3){
                //rotation needed
                if(crossVector.y > 0){
                    entity.facing -= 0.09;
                    stack.rotateAround(Axis.YN.rotationDegrees(entity.facing), 0.5F, 0, 0.5F);
                    if(entity.facing < 0) entity.facing = 359;
                }
                else{
                    entity.facing += 0.09;
                    stack.rotateAround(Axis.YN.rotationDegrees(entity.facing), 0.5F, 0, 0.5F);
                    if(entity.facing > 360) entity.facing = 1;
                }
            }
            else
            {
                entity.facing = defaultAngle;
                stack.rotateAround(Axis.YN.rotationDegrees(entity.facing), 0.5F, 0, 0.5F);
            }

            //stack.rotateAround(Axis.YN.rotationDegrees(facing), 0.5F, 0, 0.5F);
            blockRenderDispatcher.renderSingleBlock(ModBlock.PRYLAUNCHER.get().defaultBlockState(), stack, buffer, packedLight, packedOverlay);
            stack.pushPose();
            stack.popPose();
            return;
        }

        Vec3 currentPos = entity.getBlockPos().getCenter();
        Vec3 resultantVector = new Vec3(targetPos.x - currentPos.x,
                targetPos.y - currentPos.y,
                targetPos.z - currentPos.z);
        Vec3 resultantVectorHorizontal = new Vec3(resultantVector.x, 0, resultantVector.z);
        Vec3 xVector = new Vec3(0, 0, 1);

        float angle = (float) (Math.acos(resultantVectorHorizontal.dot(xVector) / (resultantVectorHorizontal.length() * xVector.length())) * (180 / Math.PI));
        if (resultantVector.x > 0) {
            angle *= -1;
        }
        angle += 180;

        Vec3 facingVector = getVectorForRotation(0, entity.facing);
        Vec3 angleVector = getVectorForRotation(0, angle);
        Vec3 crossVector = facingVector.cross(angleVector);
        float angleBetween = angleBetween2Vectors(facingVector, angleVector);

        if(angleBetween > 4){
            //rotation needed
            if(crossVector.y > 0){
                entity.facing -= 0.09;
                stack.rotateAround(Axis.YN.rotationDegrees(entity.facing), 0.5F, 0, 0.5F);
                if(entity.facing < 0) entity.facing = 359;
            }
            else{
                entity.facing += 0.09;
                stack.rotateAround(Axis.YN.rotationDegrees(entity.facing), 0.5F, 0, 0.5F);
                if(entity.facing > 360) entity.facing = 1;
            }
        }
        else{
            entity.pointingAtTarget = true;
            entity.facing = angle;
            stack.rotateAround(Axis.YN.rotationDegrees(entity.facing), 0.5F, 0, 0.5F);
        }

        blockRenderDispatcher.renderSingleBlock(ModBlock.PRYLAUNCHER.get().defaultBlockState(), stack, buffer, packedLight, packedOverlay);
        stack.pushPose();
        stack.popPose();
    }

    private Vec3 getVectorForRotation(float pitch, float yaw)
    {
        float f = (float) Math.cos(-yaw * 0.017453292F - (float)Math.PI);
        float f1 = (float) Math.sin(-yaw * 0.017453292F - (float)Math.PI);
        float f2 = (float) -Math.cos(-pitch * 0.017453292F);
        float f3 = (float) Math.sin(-pitch * 0.017453292F);
        return new Vec3(f1 * f2 * -1, f3, f * f2 * -1);
    }
    
    private float angleBetween2Vectors(Vec3 v1, Vec3 v2){
        return (float) (Math.acos(v1.dot(v2) / (v1.length() * v2.length())) * (180 / Math.PI));
    }
}

 

 

Edited by PRYtheSheep

I bang my head against the keyboard every time I code

Link to comment
Share on other sites

I figured that the Block Entity Renderer is client side only and changing the entity variables won't work. I added in packet handling to send a packet from client to server. 

ModMessages class

Spoiler
package net.mod.prymod.itemMod.networking;

import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.simple.SimpleChannel;
import net.mod.prymod.PRYmod;
import net.mod.prymod.itemMod.networking.packets.PRYBlockRendererC2SPacket;

public class ModMessages {
    private static SimpleChannel INSTANCE;
    private static int packetId = 0;
    private static int id(){
        return packetId++;
    }

    public static void register(){
        SimpleChannel net = NetworkRegistry.ChannelBuilder
                .named(new ResourceLocation(PRYmod.MODID, "main"))
                .networkProtocolVersion(() -> "1.0")
                .clientAcceptedVersions(s -> true)
                .serverAcceptedVersions(s -> true)
                .simpleChannel();

        INSTANCE = net;

        net.messageBuilder(PRYBlockRendererC2SPacket.class, id(), NetworkDirection.PLAY_TO_SERVER)
                .decoder(PRYBlockRendererC2SPacket::new)
                .encoder(PRYBlockRendererC2SPacket::toBytes)
                .consumerMainThread(PRYBlockRendererC2SPacket::handle)
                .add();
    }

    public static <MSG> void sendToServer(MSG message){
        INSTANCE.sendToServer(message);
    }

    public static <MSG> void sendToPlayer(MSG message, ServerPlayer player){
        INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), message);
    }
}

 

Packets class

Spoiler
package net.mod.prymod.itemMod.networking.packets;

import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.network.NetworkEvent;
import net.mod.prymod.ModBlock.PRYBlock;
import net.mod.prymod.ModBlock.PRYBlockEntity;

import javax.swing.text.html.parser.Entity;
import java.util.function.Supplier;

public class PRYBlockRendererC2SPacket {
    private final float facing;
    private BlockPos blockPos;

    public PRYBlockRendererC2SPacket(FriendlyByteBuf buf){
        this.facing = buf.readFloat();
        this.blockPos = buf.readBlockPos();
    }

    public PRYBlockRendererC2SPacket(float facing, BlockPos blockPos){
        this.facing = facing;
        this.blockPos = blockPos;
    }

    public void toBytes(FriendlyByteBuf buf){
        buf.writeFloat(this.facing);
        buf.writeBlockPos(this.blockPos);
    }

    public boolean handle(Supplier<NetworkEvent.Context> supplier){
        NetworkEvent.Context context = supplier.get();
        context.enqueueWork(() -> {
            //SERVER SIDE
            ServerPlayer player = context.getSender();
            ServerLevel level = (ServerLevel) player.level;
            BlockEntity entity = level.getBlockEntity(blockPos);
            if(entity instanceof PRYBlockEntity entity1){
                entity1.facing = facing;
            }
        });
        return true;
    }
}

 

The following line is called after changes is made to entity.facing in the renderer class to update the server side

ModMessages.sendToServer(new PRYBlockRendererC2SPacket(entity.facing, entity.getBlockPos()));

 

I bang my head against the keyboard every time I code

Link to comment
Share on other sites

  • PRYtheSheep changed the title to [Solved] [1.19.4] Changing block entity data from block entity renderer

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.