Jump to content

Recommended Posts

Posted

I'm currently porting to 1.10 and have a few questions.

I had a TileEntity with a custom renderer.

But a lot methods changed in the block.

 

How do I set the following in 1.10:       

 

setBlockBounds((float) START_COLLISION, (float) BOTTOM_COLLISION, (float) START_COLLISION, (float) END_COLLISION, (float) HEIGHT_COLLISION, (float) END_COLLISION); 

    @Override
    public boolean isFullCube(IBlockState state)
    {
        return false;
    }

 

Currently the block doesn't move but it is planned for the future that's why we use the TileEntitySpecialRenderer.

The entity is missing the texture and the bottom seems to be opaque.

 

package com.minecolonies.client.render;

import com.minecolonies.blocks.BlockHutField;
import com.minecolonies.client.model.ModelScarecrowBoth;
import com.minecolonies.lib.Constants;
import com.minecolonies.tileentities.ScarecrowTileEntity;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.jetbrains.annotations.NotNull;

/**
* Class to render the scarecrow.
*/
@SideOnly(Side.CLIENT)
public class TileEntityScarecrowRenderer extends TileEntitySpecialRenderer<ScarecrowTileEntity>
{
    /**
     * Offset to the block middle.
     */
    private static final double BLOCK_MIDDLE    = 0.5;
    /**
     * Y-Offset in order to have the scarecrow over ground.
     */
    private static final double YOFFSET         = 1.5;
    /**
     * Which size the scarecrow should have ingame.
     */
    private static final double SIZERATIO       = .0625;
    /**
     * Rotate the model some degrees.
     */
    private static final int    ROTATION        = 180;
    /**
     * Rotate it on the following x offset.
     */
    private static final float  XROTATIONOFFSET = 0.311F;
    /**
     * Rotate it on the following y offset.
     */
    private static final float  YROTATIONOFFSET = 0.0F;
    /**
     * Rotate it on the following z offset.
     */
    private static final float  ZROTATIONOFFSET = 2.845F;
    /**
     * Basic rotation to achieve a certain direction.
     */
    private static final int    BASIC_ROTATION  = 90;
    /**
     * Rotate by amount to go east.
     */
    private static final int    ROTATE_EAST     = 1;
    /**
     * Rotate by amount to go south.
     */
    private static final int    ROTATE_SOUTH    = 2;
    /**
     * Rotate by amount to go west.
     */
    private static final int    ROTATE_WEST     = 3;
    /**
     * The model of the scarecrow.
     */
    @NotNull
    private final ModelScarecrowBoth model;

    /**
     * The public constructor for the renderer.
     */
    public TileEntityScarecrowRenderer()
    {
        super();
        this.model = new ModelScarecrowBoth();
    }

    @Override
    public void renderTileEntityAt(@NotNull ScarecrowTileEntity te, double posX, double posY, double posZ, float partialTicks, int destroyStage)
    {
        //Store the transformation
        GlStateManager.pushMatrix();
        //Set viewport to tile entity position to render it
        GlStateManager.translate(posX + BLOCK_MIDDLE, posY + YOFFSET, posZ + BLOCK_MIDDLE);

        this.bindTexture(getResourceLocation(te));
        GlStateManager.rotate(ROTATION, XROTATIONOFFSET, YROTATIONOFFSET, ZROTATIONOFFSET);

        //In the case of worldLags tileEntities may sometimes disappear.
        if (getWorld().getBlockState(te.getPos()).getBlock() instanceof BlockHutField)
        {
            final EnumFacing facing = getWorld().getBlockState(te.getPos()).getValue(BlockHutField.FACING);
            switch (facing)
            {
                case EAST:
                    GlStateManager.rotate((float) (BASIC_ROTATION * ROTATE_EAST), 0, 1, 0);
                    break;
                case SOUTH:
                    GlStateManager.rotate((float) (BASIC_ROTATION * ROTATE_SOUTH), 0, 1, 0);
                    break;
                case WEST:
                    GlStateManager.rotate((float) (BASIC_ROTATION * ROTATE_WEST), 0, 1, 0);
                    break;
                default:
                    //don't rotate at all.
            }
        }

        this.model.render((float) SIZERATIO);
        
        /* ============ Rendering Code stops here =========== */
        //Restore the transformation, so other renderer's are not messed up.
        GlStateManager.popMatrix();
    }

    /**
     * Returns the ResourceLocation of the scarecrow texture.
     *
     * @param tileEntity the tileEntity of the scarecrow.
     * @return the location.
     */
    @NotNull
    private static ResourceLocation getResourceLocation(@NotNull ScarecrowTileEntity tileEntity)
    {
        String loc;

        if (tileEntity.getType() == ScarecrowTileEntity.ScareCrowType.PUMPKINHEAD)
        {
            loc = "textures/blocks/blockScarecrowPumpkin.pnh";
        }
        else
        {
            loc = "textures/blocks/blockScarecrowNormal.png";
        }

        return new ResourceLocation(Constants.MOD_ID + ":" + loc);
    }
}

 

package com.minecolonies.blocks;

import com.minecolonies.MineColonies;
import com.minecolonies.colony.Colony;
import com.minecolonies.colony.ColonyManager;
import com.minecolonies.creativetab.ModCreativeTabs;
import com.minecolonies.inventory.InventoryField;
import com.minecolonies.lib.Constants;
import com.minecolonies.tileentities.ScarecrowTileEntity;
import com.minecolonies.util.LanguageHandler;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.BlockDirectional;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import static net.minecraft.util.EnumFacing.*;

/**
* The class handling the fieldBlocks, placement and activation.
*/
public class BlockHutField extends BlockContainer
{
    /**
     * The position it faces.
     */
    public static final  PropertyDirection FACING           = BlockDirectional.FACING;
    //public static final PropertyDirection FACING = PropertyDirection.create("FACING", Plane.HORIZONTAL);
    /**
     * Hardness of the block.
     */
    private static final float             HARDNESS         = 10F;
    /**
     * Resistance of the block.
     */
    private static final float             RESISTANCE       = 10F;
    /**
     * Start of the collision box at y.
     */
    private static final double            BOTTOM_COLLISION = 0.0;

    /**
     * Start of the collision box at x and z.
     */
    private static final double START_COLLISION = 0.1;

    /**
     * End of the collision box.
     */
    private static final double END_COLLISION = 0.9;

    /**
     * Height of the collision box.
     */
    private static final double HEIGHT_COLLISION = 2.5;

    /**
     * Registry name for this block.
     */
    private static final String REGISTRY_NAME = "blockHutField";

    /**
     * Constructor called on block placement.
     */
    BlockHutField()
    {
        super(Material.WOOD);
        initBlock();
    }

    /**
     * Method called by constructor.
     * Sets basic details of the block.
     */
    private void initBlock()
    {
        setRegistryName(REGISTRY_NAME);
        setUnlocalizedName(Constants.MOD_ID.toLowerCase() + "." + "blockHutField");
        setCreativeTab(ModCreativeTabs.MINECOLONIES);
        //Blast resistance for creepers etc. makes them explosion proof.
        setResistance(RESISTANCE);
        //Hardness of 10 takes a long time to mine to not loose progress.
        setHardness(HARDNESS);
        this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, NORTH));
        GameRegistry.register(this);
        GameRegistry.register((new ItemBlock(this)).setRegistryName(this.getRegistryName()));
    }

    @Override
    public EnumBlockRenderType getRenderType(IBlockState state)
    {
        return EnumBlockRenderType.ENTITYBLOCK_ANIMATED;
    }

    @Override
    public int getMetaFromState(@NotNull IBlockState state)
    {
        return state.getValue(FACING).getIndex();
    }

    @Override
    public boolean isFullCube(IBlockState state)
    {
        return false;
    }

    @Override
    public boolean isPassable(IBlockAccess worldIn, BlockPos pos)
    {
        return false;
    }

    @Deprecated
    public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
    {
        return new AxisAlignedBB((float) START_COLLISION,
                                  (float) BOTTOM_COLLISION,
                                  (float) START_COLLISION,
                                  (float) END_COLLISION,
                                  (float) HEIGHT_COLLISION,
                                  (float) END_COLLISION);
    }

    @NotNull
    @Override
    @SideOnly(Side.CLIENT)
    public BlockRenderLayer getBlockLayer()
    {
        return BlockRenderLayer.SOLID;
    }

    @Override
    public boolean onBlockActivated(
                                     World worldIn,
                                     BlockPos pos,
                                     IBlockState state,
                                     EntityPlayer playerIn,
                                     EnumHand hand,
                                     @Nullable ItemStack heldItem,
                                     EnumFacing side,
                                     float hitX,
                                     float hitY,
                                     float hitZ)
    {
        //If the world is server, open the inventory of the field.
        if (!worldIn.isRemote)
        {
            @Nullable final Colony colony = ColonyManager.getColony(worldIn, pos);
            if (colony != null)
            {
                playerIn.openGui(MineColonies.instance, 0, worldIn, pos.getX(), pos.getY(), pos.getZ());
                return true;
            }
        }
        return false;
    }

    // =======================================================================
    // ======================= Rendering & IBlockState =======================
    // =======================================================================
    @Override
    public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, @Nullable EntityLivingBase placer)
    {
        @NotNull final EnumFacing enumFacing = (placer == null) ? NORTH : fromAngle(placer.rotationYaw);
        return this.getDefaultState().withProperty(FACING, enumFacing);
    }

    @Override
    public void onBlockPlacedBy(@NotNull World worldIn, @NotNull BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack)
    {
        //Only work on server side.
        if (worldIn.isRemote)
        {
            return;
        }

        if (placer instanceof EntityPlayer)
        {
            @Nullable final Colony colony = ColonyManager.getColony(worldIn, pos);

            if (colony != null)
            {
                @NotNull final InventoryField inventoryField = new InventoryField(LanguageHandler.getString("com.minecolonies.gui.inventory.scarecrow"));

                ((ScarecrowTileEntity) worldIn.getTileEntity(pos)).setInventoryField(inventoryField);
                colony.addNewField((ScarecrowTileEntity) worldIn.getTileEntity(pos), ((EntityPlayer) placer).inventory, pos, worldIn);
            }
        }
    }

    @NotNull
    @Override
    protected BlockStateContainer createBlockState()
    {
        return new BlockStateContainer(this, new IProperty[] {FACING});
    }

    @Override
    public boolean hasTileEntity(final IBlockState state)
    {
        return true;
    }

    @NotNull
    @Override
    public TileEntity createNewTileEntity(World worldIn, int meta)
    {
        return new ScarecrowTileEntity();
    }
    // =======================================================================
    // ===================== END of Rendering & Meta-Data ====================
    // =======================================================================


}

 

 

Posted
Currently the block doesn't move but it is planned for the future that's why we use the TileEntitySpecialRenderer.

 

It's not animated yet but we're planning to.

Posted

/src/main/resources/assets/minecolonies/textures/blocks/blockScarecrowPumpkin.png

 

But I'm sure that is correct (If I remove a bit of this resource location he will throw an exception that he is unable to find)

 

Constants.modId is "minecolonies"

Posted

It just renders it black and not with the texture, although he is loading the texture correctly, therefore, something is going wrong while setting it.

And renders the onclosing blocks transparent.

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.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hello! There is an issue with my world(Chocolate Edition modpack), after joining the world all creatures are frozen and the game is not responding or the game crashes after short period of time. Reproduction Steps: Turn on the game Join the world Game crashes immediately or after short period of time. Additional info: Crash log saying that an entity crashed the game is created after the crash(not the logs that I posted, different file from crash-logs, game crashed 3x by Snail, 1x by Small Snail, 1x by Tortoise) Specification: CPU: i5-13600KF GPU: GTX 1070 RAM: 32GB 3200MhZ - allocated 10GB Log links: latest.log: https://mclo.gs/Lp8zlsv crash-reports/crash: https://mclo.gs/XhtyJQI Minecraft version: 1.19.2 Modpack Version: Chocolate Edition 1.9 OS: Windows 10 Java Version: 22.0.2 Minecraft Java: Java 17
    • Hello, for several days I've been trying to find a way to add my animations in this style. @Override public void setupAnim(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { }   My current public class is : public class FakePlayerModelWithAnim<T extends FakePlayerEntity> extends EntityModel<EntityRenderState>   But i can't do that :  public class FakePlayerModelWithAnim<T extends FakePlayerEntity> extends EntityModel<T> Type parameter 'T' is not within its bound; should extend 'net.minecraft.client.renderer.entity.state.EntityRenderState' But with EntityRenderState it ok and it work !   But my setupAnim look like this :  @Override public void setupAnim(EntityRenderState p_370046_) { super.setupAnim(p_370046_); }   I don't have any access to my entity ! Look like 1.21.1 : @Override public void setupAnim(FakePlayerEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { this.root().getAllParts().forEach(ModelPart::resetPose); this.applyHeadRotation(netHeadYaw, headPitch); this.animateWalk(FakePlayerEntityAnimations.ANIM_PLAYERS_WALKING, limbSwing, limbSwingAmount, 2f, 2.5f); this.animate(entity.idleAnimationState, FakePlayerEntityAnimations.ANIM_PLAYERS_IDLE, ageInTicks, 1f); } But i'm stuck with new version of Forge...
    • Looks like an issue with abyssalsovereigns - this mod has functions that are not working on a server (client-side-only mod)
    • I added some new mods and updated old ones to my forge server and they will run successfully but the moment I try to join ill briefly load into the world and get booted with the message, internal server error. The mods in question work fine on singleplayer and removing too many from the server causes it to stop working so I cant be sure which one is causing the problem... any ideas? server log: https://pastebin.com/hGH8UUjm client log (from modrinth app): https://mclo.gs/a3oOUGY
    • The level.dat contains an invalid tag ID (115) Try to load the world in singleplayer - then test this world on the server
  • Topics

×
×
  • Create New...

Important Information

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