Jump to content

Recommended Posts

Posted

Hello all, I am creating a Cog Wheel. I've gotten it to rotate, and I can manually change it's rotation to left or right, but what I want it to do, is to see if the block next to it is going right, that I want it to go left, if the block next to it is going left, it needs to go right. Here is my render code:

 

 package com.Cutrone.Geo.render;

import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;

import org.lwjgl.opengl.GL11;

import com.Cutrone.Geo.blocks.TileEntityCogWheel;
import com.Cutrone.Geo.common.Geo_Main;

public class Cog_Wheel_Renderer extends TileEntitySpecialRenderer{

public static Cog_Wheel candle;

public static ResourceLocation texture = new ResourceLocation(Geo_Main.modid, "textures/models/Cog.png");
public Cog_Wheel_Renderer(){

	candle = new Cog_Wheel();
}


@Override
public void renderTileEntityAt(TileEntity tileentity, double d0, double d1,
		double d2, float f) {
	int rotation = 0;
	if(tileentity.getWorldObj() != null){
		rotation = tileentity.getBlockMetadata();
	}
	float size = .8F;

	TileEntityCogWheel tec = (TileEntityCogWheel) tileentity;

	GL11.glPushMatrix();

	//This makes it appear to be on the side of the block it is on.
	if(rotation == 2){
		GL11.glTranslatef((float)d0 + .5F, (float)d1 + .5F,(float)d2 + .47F);
	}else if(rotation == 3){
		GL11.glTranslatef((float)d0 + .55F, (float)d1 + .5F,(float)d2 + .5F);
	}else if(rotation == 4){
		GL11.glTranslatef((float)d0 + .55F, (float)d1 + .5F,(float)d2 + .5F);
	}else{
		GL11.glTranslatef((float)d0 + .55F, (float)d1 + .5F,(float)d2 + .5F);
	}
	if(rotation == 2){
		GL11.glRotatef(90, 180, 0F, 1F);
	}else if(rotation == 3){
		GL11.glRotatef(rotation*90*1F, 0F, 0F, 1F);
	}else if(rotation == 4){
		GL11.glRotatef(rotation*90*1F, 0F, 0F, 1F);
	}else{
		GL11.glRotatef(rotation*90*1F, 0F, 0F, 1F);
	}	


	//This rotates it left/right
	if(tec.row%2==0){
		GL11.glRotatef((float)tec.degree * 1, 0F, 1F, 0F);
	}else{
		GL11.glRotatef((float)tec.degree * -1, 0F, 1F, 0F);
	}


		GL11.glScalef(size, size - .03F, size);
		this.bindTexture(texture);
		candle.renderModel(0.0625F);

	GL11.glPopMatrix();

}

}

 

Tile Entity code:

 


public int degree = 1;
public int row = 1;

@Override
public void updateEntity(){

	if(degree < 360){
		degree++;
	}else{
		degree = 1;
	}	

}
}

 

Any help would be greatly appreciated.

Posted

Okay, second question, my mod has an option to have a special feature if another mod is installed, but when I build the mod, I get an error saying that it can not find that "dependency". In my workspace, I have the mod as an external library, where do I need to put it when I build my mod? Or what do I need to do in order to tell gradlew/forge where it is?

Posted

Okay, second question, my mod has an option to have a special feature if another mod is installed, but when I build the mod, I get an error saying that it can not find that "dependency". In my workspace, I have the mod as an external library, where do I need to put it when I build my mod? Or what do I need to do in order to tell gradlew/forge where it is?

 

If you have a totally different question, you should create a new thread post just for it.

 

Back to your original question, my first concern is that you need to figure out how to identify which blocks are the master that control the direction and which are the ones that react to the blocks.  You also have to consider how to handle case where there are blocks on either side both trying to force it in opposite directions. 

 

For example imagine you made first placed two cog blocks spinning in opposite directions with a space in between then added a third cog block in between them.

 

It is best to fully think through the logic of how you want to handle these type of situations before you start coding, otherwise it can get tricky to understand why it isn't working later.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted

Yeah, I probably should have, but I didn't want to clog up the forum with more topics. But to address your concern:

 

That is what I want to try and figure out, all I need to be able to do is have an integer that is unique to that specific instance of the block, and then a way to access it. Once I can do those, I have all the code in place to turn them and such. It is just that I can't figure out how to do that.

Posted

Yes, but before we can help we need to understand a bit more about the logic you're trying to implement.

 

For example, some questions:

- if you put one cog block down will it turn?  How do you start it turning and how do you want to set the direction?

- if you place a second cog block down next to a cog block that is already turning, I think you want it to automatically figure out which way to turn?  But what if you then try to control the second block direction manually, are you saying you'd want to then have the first cog react to that change?

- what about the scenario I mentioned above: what if you have two cogs already spinning in opposite directions with space in between and you place a new cog between them?  How will it figure out which way to turn if there are two neighboring blocks that are trying to force the direction? 

 

To be honest, it would be fairly easy to help you make code that searches around your cog block for other cog blocks and to get their directions, but after that it isn't clear how you would resolve the weird cases of multiple neighbors.  If you describe how you want the behavior to happen in the cases I listed above, it would better direct how to write the code.

 

Basically good coding "handles" all the logical cases.  For example, it might be fun to have a cog break if its neighbors are trying to force it to turn in opposite directions.  In any case, you need to have your code check for and respond to every possible case.  So list out your cases and how you want it to behave, then we can help code it.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted

Okay, second question, my mod has an option to have a special feature if another mod is installed, but when I build the mod, I get an error saying that it can not find that "dependency". In my workspace, I have the mod as an external library, where do I need to put it when I build my mod? Or what do I need to do in order to tell gradlew/forge where it is?

To be added in the build.gradle file:

dependencies {
    compile fileTree(dir:'somedirectory', include: 'somedependency.jar')
}

Posted

Okay, second question, my mod has an option to have a special feature if another mod is installed, but when I build the mod, I get an error saying that it can not find that "dependency". In my workspace, I have the mod as an external library, where do I need to put it when I build my mod? Or what do I need to do in order to tell gradlew/forge where it is?

To be added in the build.gradle file:

dependencies {
    compile fileTree(dir:'somedirectory', include: 'somedependency.jar')
}

 

And I assume the directory would be where it is located on my computer?

 

Yes, but before we can help we need to understand a bit more about the logic you're trying to implement.

 

For example, some questions:

- if you put one cog block down will it turn?  How do you start it turning and how do you want to set the direction?

- if you place a second cog block down next to a cog block that is already turning, I think you want it to automatically figure out which way to turn?  But what if you then try to control the second block direction manually, are you saying you'd want to then have the first cog react to that change?

- what about the scenario I mentioned above: what if you have two cogs already spinning in opposite directions with space in between and you place a new cog between them?  How will it figure out which way to turn if there are two neighboring blocks that are trying to force the direction? 

 

To be honest, it would be fairly easy to help you make code that searches around your cog block for other cog blocks and to get their directions, but after that it isn't clear how you would resolve the weird cases of multiple neighbors.  If you describe how you want the behavior to happen in the cases I listed above, it would better direct how to write the code.

 

Basically good coding "handles" all the logical cases.  For example, it might be fun to have a cog break if its neighbors are trying to force it to turn in opposite directions.  In any case, you need to have your code check for and respond to every possible case.  So list out your cases and how you want it to behave, then we can help code it.

 

Ah, I see.

 

-Well, the way I want it to work, is that the normal cog won't just turn, you'll have to have it turned by another cog, I am going to eventually have a block that will work like a gear box, and will turn the cogs that are touching it.

 

-If there is a conflict, I'd prefer it to work from "left to right" (west to east, and south to north) giving dominate control to the one on the left, and the ones on the right all changing and turning the direction need be, so if there is a conflict, the one on the left wins, and it sets the one on the right to the correct direction.

 

- A Cog really should be turning on its own, but if someone does place two gearboxes next to each other and has the gears turn in the same direction, I guess I could have there be a mini explosion that just took out the cogs.

 

- I intend to have the gear boxes always turn the cog in a given direction, but that shouldn't be too hard to accomplish.

 

Correct me if I am wrong here, but the way I think this would need to work would be me setting a number in the instance of the block, that would be updateable? Or is there some obviously clear and simple way that I am just not seeing?

Posted

Ah, I see.

 

-Well, the way I want it to work, is that the normal cog won't just turn, you'll have to have it turned by another cog, I am going to eventually have a block that will work like a gear box, and will turn the cogs that are touching it.

 

-If there is a conflict, I'd prefer it to work from "left to right" (west to east, and south to north) giving dominate control to the one on the left, and the ones on the right all changing and turning the direction need be, so if there is a conflict, the one on the left wins, and it sets the one on the right to the correct direction.

 

- A Cog really should be turning on its own, but if someone does place two gearboxes next to each other and has the gears turn in the same direction, I guess I could have there be a mini explosion that just took out the cogs.

 

- I intend to have the gear boxes always turn the cog in a given direction, but that shouldn't be too hard to accomplish.

 

Correct me if I am wrong here, but the way I think this would need to work would be me setting a number in the instance of the block, that would be updateable? Or is there some obviously clear and simple way that I am just not seeing?

Perfect, this makes the requirements very clear.

 

Okay, so first of all the cogs (and gearbox) should be tile entities, not standard blocks (although I guess you could use standard block with metadata if you really wanted).  With tile entities, you can make some proper variables to hold information about the state of the instance.  For example, you could have variables like a boolean clockwise variable to indicate direction of rotation, a boolean driven variable to indicate whether it is being driven by a gearbox or chain of cogs, and an int or float rotated_by variable to keep track of the amount of rotation.

 

Then regularly (perhaps every tick, although if perf is concern maybe less frequently) you would scan the neighboring locations and implement the logic you described -- if there was a gearbox attached you'd pick up the boolean clockwise variable and set the opposite (since every cog would go in opposite rotation), and if there was no gearbox you'd look for other cogs starting in the order you specified "left to right".

 

Hopefully you get the idea, and after you code it up please share and we can further give pointers if you need them.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted

With regards to performance, one way to do it is to have your cog/gear blocks notify neighbors when placed, and when your block receives notification that a neighbor changed, you can easily tell if it is a block you care about and then update the tile entity as needed. This way, you don't ever have to scan for nearby blocks.

Posted

With regards to performance, one way to do it is to have your cog/gear blocks notify neighbors when placed, and when your block receives notification that a neighbor changed, you can easily tell if it is a block you care about and then update the tile entity as needed. This way, you don't ever have to scan for nearby blocks.

 

Hmm.. that sounds good. Thanks! :)

 

Ah, I see.

 

-Well, the way I want it to work, is that the normal cog won't just turn, you'll have to have it turned by another cog, I am going to eventually have a block that will work like a gear box, and will turn the cogs that are touching it.

 

-If there is a conflict, I'd prefer it to work from "left to right" (west to east, and south to north) giving dominate control to the one on the left, and the ones on the right all changing and turning the direction need be, so if there is a conflict, the one on the left wins, and it sets the one on the right to the correct direction.

 

- A Cog really should be turning on its own, but if someone does place two gearboxes next to each other and has the gears turn in the same direction, I guess I could have there be a mini explosion that just took out the cogs.

 

- I intend to have the gear boxes always turn the cog in a given direction, but that shouldn't be too hard to accomplish.

 

Correct me if I am wrong here, but the way I think this would need to work would be me setting a number in the instance of the block, that would be updateable? Or is there some obviously clear and simple way that I am just not seeing?

Perfect, this makes the requirements very clear.

 

Okay, so first of all the cogs (and gearbox) should be tile entities, not standard blocks (although I guess you could use standard block with metadata if you really wanted).  With tile entities, you can make some proper variables to hold information about the state of the instance.  For example, you could have variables like a boolean clockwise variable to indicate direction of rotation, a boolean driven variable to indicate whether it is being driven by a gearbox or chain of cogs, and an int or float rotated_by variable to keep track of the amount of rotation.

 

Then regularly (perhaps every tick, although if perf is concern maybe less frequently) you would scan the neighboring locations and implement the logic you described -- if there was a gearbox attached you'd pick up the boolean clockwise variable and set the opposite (since every cog would go in opposite rotation), and if there was no gearbox you'd look for other cogs starting in the order you specified "left to right".

 

Hopefully you get the idea, and after you code it up please share and we can further give pointers if you need them.

 

I think I do, in short you are saying I should tell it to count how many CW there are and then determine left or right?

So, I look to see if there is a gearbox, if not, I would look to the left and see if there is a block, if there is, then I would look one more to left to see if there is, and so on, and so forth. If that is what you are saying, it actually doesn't work that well, after you place down a certain number of wheels, they start doing the disco... Is there a way for me to get a variable from another block's TileEntity?

Posted

 

Is there a way for me to get a variable from another block's TileEntity?

 

 

Okay this is the crux of your confusion -- of course you can get variables from other objects!  Once you know the tile entity instance you can just use it's variables (assuming they're public variables).  That's the point of object-oriented programming.

 

The trick then is simply finding the tile entity instance to refer to.  Like CoolAlias advises, instead of searching for the tile entities every tick, for performance reasons it is better to record them when they are added (and also update when blocks are deleted!).  So you'll just do a search when the block is added and update the entity with variables of type TileEntityCog for cogToNorth, cogToSouth, etc. and also gearboxToNorth, etc.

 

Then, in the code where you update the direction of the rotation you would simply check each direction and if it isn't null then pick up the rotation accordingly.  For example:

 

 

if (cogToNorth != null) {clockwise = !cogToNorth.clockwise};

 

if (cogToSouth != null) {clockwise = !cogToSouth.clockwise};

 

if (cogToEast != null) {clockwise = !cogToEast.clockwise};

 

if (cogToWest != null) {clockwise = !cogToWest.clockwise};

 

if (gearboxToNorth != null) {clockwise = !gearboxToNorth.clockwise};

 

if (gearboxToSouth != null) {clockwise = !gearboxToSouth.clockwise};

 

if (gearboxToEast != null) {clockwise = !gearboxToEast.clockwise};

 

if (gearboxToWest != null) {clockwise = !gearboxToWest.clockwise};

 

 

In that example, you can see how you can refer to the clockwise variable in the neighboring tile entities and the result in this case is that the last non-null neighbor would control the rotation, gearboxes would override regular cogs, and it would be set to be opposite that neighbor.

 

So hopefully you're getting the idea -- make sure the variables in your entity are public so they can be queried from other classes.

 

So what I think (double check with more experienced modders) you could do for your mod:

 

1) create block for cogs that extends ITileEntityProvider

 

2) create tile entity associated with the cogs

 

3) in the tile entity create public variables for boolean clockwise, boolean active, int rotatedByDegrees, tileEntityCog cogToNorth, etc.  (note that tile entities should automatically get x, y, z variables, world object variable, etc)

 

4) in the tile entity's constructor (more experienced programmers can advise if this is the right place) you make sure to add the tile entity to your mod's array of cogs, also search surroundings (you can just have each tile entity “look around itself” for other tile entities using TileEntityCog tile = (TileEntityCog) world.getBlockTileEntity(i, j, k); and put in the position you want to check) for neighbors and set the cogToNorth, etc. to the found instances.

 

5) in the render method you would update either the model or the texture depending on how you're visually planning to implement the cog according to the entity's active, clockwise and the rotatedByDegrees variables.

 

6) make sure you put in code in the block destroy event to update neighboring cogs such that they no longer consider the destroyed block a neighbor.

 

7) add in similar stuff for the gearboxes

 

8) don't forget to registers all your stuff, update lang file, texture assets, etc. (I'm using 1.7.2, so maybe different if you're on 1.6.4)

 

Anyway, hopefully you're getting an idea of a proposed approach:

 

- extend your blocks with tile entities to keep track of variables

 

- implement variables in the tile entity that track its state and also instances of any neighbors

 

- refer to variables in those instances to figure out how neighbors should affect each instance

 

- render the effect of cog turning

 

 

 

 

 

 

 

 

 

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted

 

Is there a way for me to get a variable from another block's TileEntity?

 

 

Okay this is the crux of your confusion -- of course you can get variables from other objects!  Once you know the tile entity instance you can just use it's variables (assuming they're public variables).  That's the point of object-oriented programming.

 

The trick then is simply finding the tile entity instance to refer to.  Like CoolAlias advises, instead of searching for the tile entities every tick, for performance reasons it is better to record them when they are added (and also update when blocks are deleted!).  So you'll just do a search when the block is added and update the entity with variables of type TileEntityCog for cogToNorth, cogToSouth, etc. and also gearboxToNorth, etc.

 

Then, in the code where you update the direction of the rotation you would simply check each direction and if it isn't null then pick up the rotation accordingly.  For example:

 

 

if (cogToNorth != null) {clockwise = !cogToNorth.clockwise};

 

if (cogToSouth != null) {clockwise = !cogToSouth.clockwise};

 

if (cogToEast != null) {clockwise = !cogToEast.clockwise};

 

if (cogToWest != null) {clockwise = !cogToWest.clockwise};

 

if (gearboxToNorth != null) {clockwise = !gearboxToNorth.clockwise};

 

if (gearboxToSouth != null) {clockwise = !gearboxToSouth.clockwise};

 

if (gearboxToEast != null) {clockwise = !gearboxToEast.clockwise};

 

if (gearboxToWest != null) {clockwise = !gearboxToWest.clockwise};

 

 

In that example, you can see how you can refer to the clockwise variable in the neighboring tile entities and the result in this case is that the last non-null neighbor would control the rotation, gearboxes would override regular cogs, and it would be set to be opposite that neighbor.

 

So hopefully you're getting the idea -- make sure the variables in your entity are public so they can be queried from other classes.

 

So what I think (double check with more experienced modders) you could do for your mod:

 

1) create block for cogs that extends ITileEntityProvider

 

2) create tile entity associated with the cogs

 

3) in the tile entity create public variables for boolean clockwise, boolean active, int rotatedByDegrees, tileEntityCog cogToNorth, etc.  (note that tile entities should automatically get x, y, z variables, world object variable, etc)

 

4) in the tile entity's constructor (more experienced programmers can advise if this is the right place) you make sure to add the tile entity to your mod's array of cogs, also search surroundings (you can just have each tile entity “look around itself” for other tile entities using TileEntityCog tile = (TileEntityCog) world.getBlockTileEntity(i, j, k); and put in the position you want to check) for neighbors and set the cogToNorth, etc. to the found instances.

 

5) in the render method you would update either the model or the texture depending on how you're visually planning to implement the cog according to the entity's active, clockwise and the rotatedByDegrees variables.

 

6) make sure you put in code in the block destroy event to update neighboring cogs such that they no longer consider the destroyed block a neighbor.

 

7) add in similar stuff for the gearboxes

 

8) don't forget to registers all your stuff, update lang file, texture assets, etc. (I'm using 1.7.2, so maybe different if you're on 1.6.4)

 

Anyway, hopefully you're getting an idea of a proposed approach:

 

- extend your blocks with tile entities to keep track of variables

 

- implement variables in the tile entity that track its state and also instances of any neighbors

 

- refer to variables in those instances to figure out how neighbors should affect each instance

 

- render the effect of cog turning

 

Thank you so much! The bolded words where the only things I didn't have, there it goes. Now to see if I can implement it. I'll post an update when I finish the code for these. Thanks man!

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.