我正在为Minecraft开发一个mod,它允许用户创建类似于RedPower方式的大型移动结构。可用来源here 我正在使用伪造1.8-11.14.1.1357,我试图检查一个块是否通过另一个块或直接连接到控制器块。但是,由于递归变深,我当前的方法会引发StackOverflow错误。我该如何简化代码,以便在可能的情况下避免递归。
public boolean isAttachedToController(BlockPos pos, World world) {
IBlockState state;
boolean up;
state = world.getBlockState(pos.up());
if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) {
up = true;
} else {
if (Arrays.asList(Stuff.getConfig().get("allowed_blocks", "Blocks", new String[]{}).getStringList()).contains(state.getBlock().getClass().getCanonicalName())) {
up = isAttachedToController(pos.up(), world);
} else {
up = false;
}
}
boolean down;
state = world.getBlockState(pos.down());
if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) {
down = true;
} else {
if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) {
down = isAttachedToController(pos.down(), world);
} else {
down = false;
}
}
boolean north;
state = world.getBlockState(pos.north());
if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) {
north = true;
} else {
if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) {
north = isAttachedToController(pos.north(), world);
} else {
north = false;
}
}
boolean south;
state = world.getBlockState(pos.south());
if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) {
south = true;
} else {
if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) {
south = isAttachedToController(pos.south(), world);
} else {
south = false;
}
}
boolean east;
state = world.getBlockState(pos.east());
if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) {
east = true;
} else {
if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) {
east = isAttachedToController(pos.up(), world);
} else {
east = false;
}
}
boolean west;
state = world.getBlockState(pos.west());
if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) {
west = true;
} else {
if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) {
west = isAttachedToController(pos.west(), world);
} else {
west = false;
}
}
return up || down || north || south || east || west;
}
Stacktrace作为GitHub Gist here提供 BlockMovingController.java源here
答案 0 :(得分:0)
您的问题是您的方法没有终止。
up = isAttachedToController(pos.up(), world);
这一行是你的问题:它基本上会无限期地上升,因为第一个块没有控制器,然后询问上面的块。这个控制器顶部没有控制器,但它不会终止,而是再次询问上面的块。
看看下面的代码。使用参数checkNextBlock = true
调用它可以解决问题。
public boolean isAttachedToController(BlockPos pos, World world, boolean checkNextBlock) {
IBlockState state;
// check the block above
state = world.getBlockState(pos.up());
if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) {
return true;
} else {
if(checkNextBlock)
if (Arrays.asList(Stuff.getConfig().get("allowed_blocks", "Blocks", new String[]{}).getStringList()).contains(state.getBlock().getClass().getCanonicalName())) {
if(isAttachedToController(pos.up(), world, false))
return true;
}
}
// check the block below
state = world.getBlockState(pos.down());
if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) {
return true;
} else {
if(checkNextBlock)
if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) {
if(isAttachedToController(pos.down(), world, false))
return true;
}
}
// check the nothen block
state = world.getBlockState(pos.north());
if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) {
return true;
} else {
if(checkNextBlock)
if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) {
if(isAttachedToController(pos.north(), world, false))
return true;
}
}
// check the southen block
state = world.getBlockState(pos.south());
if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) {
return true;
} else {
if(checkNextBlock)
if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) {
if(isAttachedToController(pos.south(), world, false))
return true;
}
}
// check the eastern block
state = world.getBlockState(pos.east());
if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) {
return true;
} else {
if(checkNextBlock)
if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) {
if(isAttachedToController(pos.up(), world, false))
return true;
}
}
// Check the western block
state = world.getBlockState(pos.west());
if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) {
return true;
} else {
if(checkNextBlock)
if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) {
if(isAttachedToController(pos.west(), world, false))
return true;
}
}
return false;
}