Jump to content

[Solved] Techne model as block not placed with proper rotation?


Recommended Posts

Posted

I can't seem to get my techne models-as-blocks to be properly rotated when they are placed by the player. No matter what I've tried, the model will not rotate.

 

I think my problem is in public void onBlockPlacedBy. Any help greatly appreciated.

 

ecZK31Z.png

 

Here is my block class:

 

package whalecraft.doors;

import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.EntityLiving;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;

public class BlockCustomTable extends BlockContainer {

public BlockCustomTable(int par1, Material material) {
	super(par1, material);
	this.setCreativeTab(CreativeTabs.tabDecorations);
	this.setHardness(20.0F);
	this.setResistance(0.4F);
	//this.setLightValue(0.1F);
}

    //Make sure you set this as your TileEntity class relevant for the block!
@Override
public TileEntity createNewTileEntity(World world) {
	return new TileEntityTableWoodLight();
}

    //You don't want the normal render type, or it wont render properly.
    @Override
    public int getRenderType() {
            return -1;
    }
   
    //It's not an opaque cube, so you need this.
    @Override
    public boolean isOpaqueCube() {
            return false;
    }
   
    //It's not a normal block, so you need this too.
    public boolean renderAsNormalBlock() {
            return false;
    }

    //This is the icon to use for showing the block in your hand.

    public void registerIcons(IconRegister iconRegister)
    {
        this.blockIcon = iconRegister.registerIcon("doormod:table_wood_light");
  
}

public void onBlockPlacedBy(World world, int i, int j, int k, EntityLiving entityLiving){
int rotation = MathHelper.floor_double((double)((entityLiving.rotationYaw * 4.0f) / 360F) + 2.5D) & 3;
}
}

 

Here is the renderer class:

 

package whalecraft.doors;

import org.lwjgl.opengl.GL11;

import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;

public class TileEntityTableWoodLightRenderer extends TileEntitySpecialRenderer {

private final ModelTable model;

    public TileEntityTableWoodLightRenderer() {
        this.model = new ModelTable();
    }

    private void adjustRotatePivotViaMeta(World world, int x, int y, int z) {
        int meta = world.getBlockMetadata(x, y, z);
        GL11.glPushMatrix();
        GL11.glRotatef(meta * (-90), 0.0F, 0.0F, 1.0F);
        GL11.glPopMatrix();
    }    
    
    @Override
    public void renderTileEntityAt(TileEntity te, double x, double y, double z, float scale) {
        GL11.glPushMatrix();
        GL11.glTranslatef((float) x + 0.5F, (float) y + 1.5F, (float) z + 0.5F);
        ResourceLocation textures = (new ResourceLocation("doormod:/textures/entity/table_wood_light.png"));
        Minecraft.getMinecraft().renderEngine.bindTexture(textures);
        GL11.glPushMatrix();
        GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F);
        this.model.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F);
        GL11.glPopMatrix();
        GL11.glPopMatrix();
    }

    private void adjustLightFixture(World world, int i, int j, int k, Block block) {
        Tessellator tess = Tessellator.instance;
        float brightness = block.getBlockBrightness(world, i, j, k);
        int skyLight = world.getLightBrightnessForSkyBlocks(i, j, k, 0);
        int modulousModifier = skyLight % 65536;
        int divModifier = skyLight / 65536;
        tess.setColorOpaque_F(brightness, brightness, brightness);
        OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit,  (float) modulousModifier,  divModifier);
    }
}

Posted

public void onBlockPlacedBy(World world, int i, int j, int k, EntityLiving entityLiving){
int rotation = MathHelper.floor_double((double)((entityLiving.rotationYaw * 4.0f) / 360F) + 2.5D) & 3;
}

 

Congradulations, this function DOES NOTHING.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Congratulations*, you're not helpful!

 

*The D was intentional.

 

And I was, actually.  You calculated a rotation, and then didn't do anything with it.

 

I went through a lot of tutorials to even get the model working. None of them actually explained anything. I'm just looking for some help.

 

I am helping.  I pointed out where your problem is, I'm just not telling you the solution.

Hint: you're accessing the block's metadata to determine which direction to rotate the model.  Where are you setting the metadata?

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

This took me forever to figure out.  What ou have to do is in your onBlockPlacedBy method

int par7 = MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;

.  This will get the rotation of the player who placed your block.  Then, based on that number (it will return 0, 1, 2, or 3) set the metadata of the block. 

Next, go into the render code.  Do int rotation = TileEntityWhatever.getMetadata(). Then set your rotation to a scale of 90. Lastly, do GL11.glRotatef(scale, 0.0F, 1.0F, 0.0F);

This render part is really confusing, so i've posted my render code.

@Override
public void renderTileEntityAt(TileEntity tileentity, double d0, double d1, double d2, float f) {
	TileEntityCannon cannonTE = (TileEntityCannon)tileentity;
	this.bindTexture(texture);
	GL11.glPushMatrix();
	GL11.glTranslatef((float) d0 + 0.5F, (float) d1 + 1.5F, (float) d2 + 0.5F);
	GL11.glScalef(1.0F, -1F, -1F);
	int rotation = cannonTE.getMetadata(
			); 
	if(rotation == 3){
            scale = -90;
        }

        if(rotation == 2){
            scale = 90;
        }

        if(rotation == 5){
            scale = 180;
        }

        if(rotation == 4){
            scale = 0;
        }
        GL11.glRotatef(scale, 0.0F, 1.0F, 0.0F);
	GL11.glRotatef(90, 0, 1.0F, 0);
	this.model.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F);
	GL11.glPopMatrix(); 
}

 

Im only feeding you code because this was very difficult and time consuming to figure out :P

Posted

Im only feeding you code because this was very difficult and time consuming to figure out :P

 

Yeah, after spending a few hours to figure something out I figure it is time to go to the forums and stop wasting effort. So, thanks for the help!

 

As for actually trying to implement your solution, I am having trouble setting the metadata of the block. I've added a onActivated text message to query the metadata, and it is always 0.

 

Here is my attempt to set the metadata of the block:

 

public void onBlockPlacedBy(World world, int i, int j, int k, EntityLiving entityLiving){

    int rotation = MathHelper.floor_double((double)(entityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
world.setBlockMetadataWithNotify(i, j, k, rotation, 2);
}

 

I am pretty sure that the i, j, k are the coordinates of the entityLiving (player) that drops the block rather than the block itself (so, always 0 since the block the player is in is air). Is this the case? If so, how do I reference the actual dropped block? Any help?

Posted

1) I'm pretty sure you're wrong, as I use that function for my TE block

2) There's also onBlockAddedToWorld

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

What I would do is put is:

 

 

This in my Block class:

Method: setDefaultDirection(World world, int x, int y, int z) {
	if(!world.isRemote) {
	int zNeg = world.getBlockId(x, y, z - 1);
	int zPos = world.getBlockId(x, y, z + 1);
	int xNeg = world.getBlockId(x - 1, y, z);
	int xPos = world.getBlockId(x + 1, y, z);
	byte meta = 3;

	if(Block.opaqueCubeLookup[xNeg] && !Block.opaqueCubeLookup[xPos]) meta = 5;
	if(Block.opaqueCubeLookup[xPos] && !Block.opaqueCubeLookup[xNeg]) meta = 4;
	if(Block.opaqueCubeLookup[zNeg] && !Block.opaqueCubeLookup[zPos]) meta = 3;
	if(Block.opaqueCubeLookup[zPos] && !Block.opaqueCubeLookup[zNeg]) meta = 2;

	world.setBlockMetadataWithNotify(x, y, z, meta, 2);
	}
	}


	Methos: onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entity, ItemStack itemstack) {
	int rotation = MathHelper.floor_double((double)(entity.rotationYaw * 4F / 360F) + 0.5D) & 3;

	if(rotation == 0) {
	world.setBlockMetadataWithNotify(x, y, z, 2, 2);
	}

	if(rotation == 1) {
	world.setBlockMetadataWithNotify(x, y, z, 5, 2);
	}

	if(rotation == 2) {
	world.setBlockMetadataWithNotify(x, y, z, 3, 2);
	}

	if(rotation == 3) {
	world.setBlockMetadataWithNotify(x, y, z, 4, 2);
	}
	}

This in my Renderer's class:

GL11.glPushMatrix();
	GL11.glTranslatef((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F);
	GL11.glRotatef(180F, 0F, 0F, 1F);
	int i = tileentity.getBlockMetadata();

	short short1 = 0;

	if (i == 2)
        {
            short1 = 360;
        }

        if (i == 3)
        {
            short1 = 180;
        }

        if (i == 4)
        {
            short1 = -90;
        }

        if (i == 5)
        {
            short1 = 90;
        }
        GL11.glRotatef((float)short1, 0.0F, 1.0F, 0.0F);
        
        

	this.bindTexture(texture);
	GL11.glPushMatrix();
	this.model.renderModel(0.0625F);
	GL11.glPopMatrix();
	GL11.glPopMatrix();

 

Don't just copy and paste actually learn from this.

Also you may need to edit some of the numbers and variables here.

Don't be afraid to ask question when modding, there are no stupid question! Unless you don't know java then all your questions are stupid!

Posted

That method won't do anything on its own, it needs to be called from somewhere.

 

Also, I don't think his block cares about adjacent solid blocks the way a furnace does.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

1) I'm pretty sure you're wrong, as I use that function for my TE block

2) There's also onBlockAddedToWorld

 

Hmm, ok, thanks for letting me know it is not an issue with the function (isn't it a method?) being used.

 

I think I might delete everything and just try again from scratch. I'll also try 'onBlockAddedToWorld'

 

That method won't do anything on its own, it needs to be called from somewhere.

 

You are talking about Mecblader's solution, right? As onBlockPlacedBy is called when the block is placed by a living entity, right?

 

@Mecblader

I have been trying to learn from the 'tutorials' on using techne models. The problem is that they are often like throwing you into the deep end of a pool, there is no slower build up or explanation of smaller bits of code. My main problem is not understanding much of the GL11 functions. I think I'll break it down even simpler and perhaps assign a random metadata between 0-3 and assign rotation based on that. And then move on to have its rotation based on the facing of the placing player. This seems like a way to learn as I already understand how to place a static techne model-as-block.

 

EDIT: Ok, ROTATION WORKS! The problem is only with setting the metadata. If i set a given metadata when I right click the model, it will rotate it appropriately.

 

Even if I try to just set a static value in my onBlockPlacedBy it does not work... i.e.

 

    public void onBlockPlacedBy(World world, int x, int y, int z, EntityLiving entityLiving, ItemStack par6ItemStack){
    	world.setBlockMetadataWithNotify(x, y, z, 2, 2);
}

 

This does not work. However, if I set the metadata to 2 using the onBlockActivated it does work. So clearly I am doing something wrong in onBlockPlacedBy.

Posted

Oh yes, about the metadata.  I forgot to mention that :P  i believe you need to add that as a nbt tag in your tile entity.  It will force save the metadata.  Im pretty sure thats how I have it, I can double check when I get home.

Posted
EDIT: Ok, ROTATION WORKS! The problem is only with setting the metadata. If i set a given metadata when I right click the model, it will rotate it appropriately.

 

Even if I try to just set a static value in my onBlockPlacedBy it does not work... i.e.

 

    public void onBlockPlacedBy(World world, int x, int y, int z, EntityLiving entityLiving, ItemStack par6ItemStack){
    	world.setBlockMetadataWithNotify(x, y, z, 2, 2);
}

 

This does not work. However, if I set the metadata to 2 using the onBlockActivated it does work. So clearly I am doing something wrong in onBlockPlacedBy.

 

Sounds like a problem with that function.  Add @Override just before it.

 

Oh yes, about the metadata.  I forgot to mention that :P  i believe you need to add that as a nbt tag in your tile entity.  It will force save the metadata.  Im pretty sure thats how I have it, I can double check when I get home.

 

That's not a "force save of the metadata" it's just a more complicated and memory inefficient way of saving the same info in a different way.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

I did try to override, but I get the error "The method onBlockPlacedBy(World, int, int, int, EntityLiving, ItemStack) of type BlockCustomTable must override or implement a supertype method" despite this being a method found in Block.

 

I had eclipse auto-add the method to block just to compare them, and they appear to be the exact same thing.

Posted

Alright so turns out thats not what I did.  I dont know why, but for some reason my metadata values are 2, 3, 4, and 5. Also my render code draws from a getMetadata method I made.  For some reason, all this stuff works and it didnt with the obvious solution.

My getMetadata method is just two lines, and it returns the metadata of that instance of a tile entity in the given world.

Posted

I did try to override, but I get the error "The method onBlockPlacedBy(World, int, int, int, EntityLiving, ItemStack) of type BlockCustomTable must override or implement a supertype method" despite this being a method found in Block.

 

I had eclipse auto-add the method to block just to compare them, and they appear to be the exact same thing.

 

EntityLiving != EntityLivingBase

 

Your function is not identical to the function in the Block class (which is why the @Override is throwing an error and why the function is not being called).

 

Ahh, figured it out. You need to use the same variable names and not just the same variable order. Heh. Didn't think of this as this is not the way it works in C#, if I recall correctly.

 

Not variable name, variable type.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

I did try to override, but I get the error "The method onBlockPlacedBy(World, int, int, int, EntityLiving, ItemStack) of type BlockCustomTable must override or implement a supertype method" despite this being a method found in Block.

 

I had eclipse auto-add the method to block just to compare them, and they appear to be the exact same thing.

 

EntityLiving != EntityLivingBase

 

Your function is not identical to the function in the Block class (which is why the @Override is throwing an error and why the function is not being called).

 

Ahh, figured it out. You need to use the same variable names and not just the same variable order. Heh. Didn't think of this as this is not the way it works in C#, if I recall correctly.

 

Not variable name, variable type.

 

Great! Now I don't have to use those messy variable names.

 

Could I inquire what mod ur making? Thats an interesting model and I cant think what you would use that for

 

Really, I am just going through every idea I have and making sure I can implement them; so, this is basically a learning process. I've done a whole bunch of stuff like pillars that change their textures so the top and bottom look like a pillar (will probably re-do those as techne models), overridden default recipes to add stuff (got rid of vanilla door and added doors for each wood), custom crops, custom mushrooms, etc., I think this is a good way to learn before getting into modding and I've done this process for other games I've done modding in (zDoom, Terraria, FTL, etc.,)

 

This model is just a table decoration with an arrow on it for debugging. Going to make it extend into a long 2 block table when another table is placed next to it in the way vanilla chests behave.

 

Also, THANK YOU EVERYONE. Here is the fruit of our endeavors:

 

TyD1H8T.png

Posted

Pretty smart actually :P

For two blocks if u need help, pm me, the block I use with a custom model is two blocks long, so its far more complex because its not like a chest.

If it is like a chest, good luck :P

Just wondering, you should try 3D in-hand models.  They look really cool and are fairly simple :)

Posted

Alright so turns out thats not what I did.  I dont know why, but for some reason my metadata values are 2, 3, 4, and 5. Also my render code draws from a getMetadata method I made.  For some reason, all this stuff works and it didnt with the obvious solution.

My getMetadata method is just two lines, and it returns the metadata of that instance of a tile entity in the given world.

 

Just set up a Techne ladder and, during the process of making it work like a ladder, I noticed ladders use 2, 3, 4, and 5 as their metadata for facing. That is probably why you have it set up like that. Just something I noticed that might be useful.

 

Edit: Also, this is cool:

 

tprenyE.png

Posted

Yeah I understand that it may be difficult to learn all of this code and the way minecraft does stuff, but it is really worth it in the end. I remember when i learned ho to make the block rotate, the only issue I had was that I did not have the help of other people because I did not know of this section in the forge website.

 

Tip for the future: Despite it being very tempting to copy and paste, a good way to learn how to do stuff yourself is to use source code from professional mods, but not too professional like BuildCraft because that mod is confusing to understand how it works.

 

Few mods I use as reference material:

 

  • BuildCraft(Despite it being confusing, some parts are useful to the average modder)

  • EquivilantExchange3

  • IronChests

  • Any other open source forge mods

[*]

 

 

Don't be afraid to ask question when modding, there are no stupid question! Unless you don't know java then all your questions are stupid!

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

    • that happens every time I enter a new dimension.
    • This is the last line before the crash: [ebwizardry]: Synchronising spell emitters for PixelTraveler But I have no idea what this means
    • What in particular? I barely used that mod this time around, and it's never been a problem in the past.
    • Im trying to build my mod using shade since i use the luaj library however i keep getting this error Reason: Task ':reobfJar' uses this output of task ':shadowJar' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. So i try adding reobfJar.dependsOn shadowJar  Could not get unknown property 'reobfJar' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler. my gradle file plugins { id 'eclipse' id 'idea' id 'maven-publish' id 'net.minecraftforge.gradle' version '[6.0,6.2)' id 'com.github.johnrengelman.shadow' version '7.1.2' id 'org.spongepowered.mixin' version '0.7.+' } apply plugin: 'net.minecraftforge.gradle' apply plugin: 'org.spongepowered.mixin' apply plugin: 'com.github.johnrengelman.shadow' version = mod_version group = mod_group_id base { archivesName = mod_id } // Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. java.toolchain.languageVersion = JavaLanguageVersion.of(17) //jarJar.enable() println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" minecraft { mappings channel: mapping_channel, version: mapping_version copyIdeResources = true runs { configureEach { workingDirectory project.file('run') property 'forge.logging.markers', 'REGISTRIES' property 'forge.logging.console.level', 'debug' arg "-mixin.config=derp.mixin.json" mods { "${mod_id}" { source sourceSets.main } } } client { // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. property 'forge.enabledGameTestNamespaces', mod_id } server { property 'forge.enabledGameTestNamespaces', mod_id args '--nogui' } gameTestServer { property 'forge.enabledGameTestNamespaces', mod_id } data { workingDirectory project.file('run-data') args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') } } } sourceSets.main.resources { srcDir 'src/generated/resources' } repositories { flatDir { dirs './libs' } maven { url = "https://jitpack.io" } } configurations { shade implementation.extendsFrom shade } dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" implementation 'org.luaj:luaj-jse-3.0.2' implementation fg.deobf("com.github.Virtuoel:Pehkui:${pehkui_version}") annotationProcessor 'org.spongepowered:mixin:0.8.5:processor' minecraftLibrary 'luaj:luaj-jse:3.0.2' shade 'luaj:luaj-jse:3.0.2' } // Example for how to get properties into the manifest for reading at runtime. tasks.named('jar', Jar).configure { manifest { attributes([ 'Specification-Title' : mod_id, 'Specification-Vendor' : mod_authors, 'Specification-Version' : '1', // We are version 1 of ourselves 'Implementation-Title' : project.name, 'Implementation-Version' : project.jar.archiveVersion, 'Implementation-Vendor' : mod_authors, 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), "TweakClass" : "org.spongepowered.asm.launch.MixinTweaker", "TweakOrder" : 0, "MixinConfigs" : "derp.mixin.json" ]) } rename 'mixin.refmap.json', 'derp.mixin-refmap.json' } shadowJar { archiveClassifier = '' configurations = [project.configurations.shade] finalizedBy 'reobfShadowJar' } assemble.dependsOn shadowJar reobf { re shadowJar {} } publishing { publications { mavenJava(MavenPublication) { artifact jar } } repositories { maven { url "file://${project.projectDir}/mcmodsrepo" } } } my entire project:https://github.com/kevin051606/DERP-Mod/tree/Derp-1.0-1.20
  • Topics

×
×
  • Create New...

Important Information

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