This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Bubba's profile picture

Strange shifting peripheral functions

Started by Bubba, 24 November 2012 - 05:05 PM
Bubba #1
Posted 24 November 2012 - 06:05 PM
Hello,
I have recently released my AdventureMap peripheral and now that I've sat down to do some lua coding I've encountered a weird issue. This issue only happens in the compiled version (or at least I have not encountered it in the decompiled one).

What happens is this:
I have a peripheral function called "peripheral.findComputer()" which finds the x,y,z coordinates of the computer attached to the peripheral. The function works fine for a while, but for some reason after about five minutes or so the function starts calling "peripheral.playerCoords()", which gets the coordinates of the player. The peripheral.findComputer() function requires no arguments, and the peripheral.playerCoords() function does.

Here are some screenshots:
Working:
Spoiler

Not working (several minutes later):
Spoiler

It seems to be a problem localized to each created world as creating a new world fixes the problem for several minutes before it reverts back to the broken state. Here is the relevant java code:

//Get the method names
public String[] getMethodNames()
{
return new String[] { "getBlock", "setBlock", "findPeripheral", "findComputer","playerCoords", "getHealth", "attackPlayer","setPlayerPos", "givePlayer", "getPlayers", "say", "createFireball", "playerLooking", "createExplosion" };
}

//later in the file

case 3: {
int cX = this.xCoord;
int cY = this.yCoord;
int cZ = this.zCoord;
for (int x=cX-3; x<=cX+3; x++) {
for (int y=cY-3; y<=cY+3;y++) {
for (int z=cZ-3;z<=cZ+3; z++) {
if (worldObj.getBlockId(x,y,z) == 210 || worldObj.getBlockId(x,y,z) == 207) {
return new Object[] {x,y,z};
}
}
}
}

//immediately after the previous code
case 4: {
if (arguments.length < 1) {
return new Object[] {false, "Requires a string"};
} else {
World world = this.worldObj;
EntityPlayer player = world.getPlayerEntityByName((String) arguments[0]);
if (player == null) {
return new Object[] {null};
} else {
return new Object[] {player.posX, player.posY, player.posZ};
}
}
}
}

Here is a link to the entire file in case it is for some reason necessary: http://pastebin.com/GFg6b02K

My method of finding the computer's location is terrible (and temporary), but it shouldn't be effecting what method is called when I use these functions. It is especially strange to me that it would work temporarily but then change for no apparent reason.

And before anyone asks, yes I have recompiled the peripheral and done testing in eclipse debugging mode. It worked fine in eclipse debugging mode, but as soon as I compile it and run it the regular way, it does this.

Any help would be greatly appreciated.
Xfel #2
Posted 24 November 2012 - 11:21 PM
You forgot the break in the switch-case here. If you don't put it at the end of a case block, the execution will continue into the next block. See also: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
Cloudy #3
Posted 25 November 2012 - 02:37 AM
I note that your code is rigidly linked to hard coded block ID's too (and you missed one - turtles have two block ID's!) - as you most likely have a deobsfucated version of CC anyway, you are best referring directly to the block ID's inside the ComputerCraft and CCTurtle classes. I will expose those in a future API update so that you can detect if a block is a Computer or not.
Bubba #4
Posted 25 November 2012 - 05:19 AM
You forgot the break in the switch-case here. If you don't put it at the end of a case block, the execution will continue into the next block. See also: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html

Ah thank you. I'm pretty new to java so simple stuff like that is not obvious to me.
Edit: Quick question, can I do it like this? Eclipse tells me that this code is unreachable, which makes sense considering the fact that I always return a value.

case 0: {
        		if (arguments.length < 3) {
        			return new Object[] {false, "Requires 3 arguments"};
        		} else {
        		World world = this.worldObj;
    			int x = ((Double) arguments[0]).intValue();
    			int y = ((Double) arguments[1]).intValue();
    			int z = ((Double) arguments[2]).intValue();
    			return new Object[] {world.getBlockId(x, y, z)};
        		}
        		break; // I don't see how it would ever reach this
        	}

Edit 2: Looking at the default code from ComputerCraft (TileEntityMonitor, specifically) I see no break statements after switch cases. There is always a return statement, yes, but no break statements. What gives?

I note that your code is rigidly linked to hard coded block ID's too (and you missed one - turtles have two block ID's!) - as you most likely have a deobsfucated version of CC anyway, you are best referring directly to the block ID's inside the ComputerCraft and CCTurtle classes. I will expose those in a future API update so that you can detect if a block is a Computer or not.

Yeah I had not planned for my current method to be permanent but I had forgotten about it up to now. If I refer directly to the block ID's inside CC and CCTurtle will those values reflect the values in the config file?
Edit: Nevermind. I looked at the code and it looks like it does indeed reflect the values in the config file. Should have looked before asking.
Bubba #5
Posted 25 November 2012 - 06:22 AM
Nevermind guys, I figured out what I was doing wrong. That was the only statement that didn't have a return object[] outside of the if statement. Thanks for your help.