我们今天对 主世界建筑生成进行制作
1.在 util 包中新建 IStructure 接口
在 IStructure.java 中编写
package com.Joy187.newmod.util;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.world.WorldServer;
import net.minecraft.world.gen.structure.template.PlacementSettings;
import net.minecraftforge.fml.common.FMLCommonHandler;
public interface IStructure {
public static final WorldServer worldServer = FMLCommonHandler.instance().getMinecraftServerInstance().getWorld(0);
public static final PlacementSettings settings = (new PlacementSettings()).setChunk(null).setIgnoreEntities(false).setIgnoreStructureBlock(false).setMirror(Mirror.NONE).setRotation(Rotation.NONE);
}
2.在world 包中新建 ModWorldGenStructure 类
在 ModWorldGenStructure.java 中编写
package com.Joy187.newmod.world;
import java.util.Random;
import com.Joy187.newmod.util.IStructure;
import com.Joy187.newmod.util.Reference;
import net.minecraft.block.state.IBlockState;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.gen.feature.WorldGenerator;
import net.minecraft.world.gen.structure.template.Template;
import net.minecraft.world.gen.structure.template.TemplateManager;
public class ModWorldGenStructure extends WorldGenerator implements IStructure{
public static String structureName;
public ModWorldGenStructure(String name) {
this.structureName = name;
}
@Override
public boolean generate(World worldIn, Random rand, BlockPos position) {
this.generateStructure(worldIn, position);
return true;
}
public static void generateStructure(World world,BlockPos pos) {
MinecraftServer mcServer = world.getMinecraftServer();
TemplateManager manager = worldServer.getStructureTemplateManager();
ResourceLocation location = new ResourceLocation(Reference.Mod_ID, structureName);
Template template = manager.get(mcServer,location);
if(template != null) {
IBlockState state = world.getBlockState(pos);
world.notifyBlockUpdate(pos, state, state, 3);
template.addBlocksToWorldChunk(world, pos, settings);
}
}
}
3.在 world 包中新建ModWorldGenCustomStructure 类
在ModWorldGenCustomStructure.java 中编写
package com.Joy187.newmod.world;
import java.util.ArrayList;
import java.util.Random;
import com.Joy187.newmod.blocks.MutamyceteBlock;
import com.Joy187.newmod.init.ModBlocks;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.WorldType;
import net.minecraft.world.biome.BiomePlains;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraft.world.gen.feature.WorldGenerator;
import net.minecraftforge.fml.common.IWorldGenerator;
import scala.actors.threadpool.Arrays;
public class ModWorldGenCustomStructure implements IWorldGenerator{
//你所要生成的建筑名称,可以写多个建筑
public static final ModWorldGenStructure XCHAMBERX = new ModWorldGenStructure("xchamberx");
@Override
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkePrvider) {
switch(world.provider.getDimension())
{
case 2:
break;
case 1:
break;
case 0: //建筑名称 生成的时间 随机位 区块X,Z 生成概率(0~100) 在什么方块上面生成 在什么地形生成
generateStructure(XCHAMBERX, world, random, chunkX, chunkZ, 10, Blocks.GRASS, BiomePlains.class);
break;
case -1:
}
}
private void generateStructure(WorldGenerator generator , World world, Random random, int chunkX, int chunkZ, int chance, Block topBlock, Class<?>... classes) {
ArrayList<Class<?>> classesList = new ArrayList<Class<?>>(Arrays.asList(classes));
int x = (chunkX * 16) + random.nextInt(15);
int z = (chunkZ * 16) + random.nextInt(15);
int y = calculateGenerationHeight(world, x, z,topBlock);
BlockPos pos = new BlockPos(x,y,z);
Class<?> biome = world.provider.getBiomeForCoords(pos).getClass();
if(world.getWorldType() != WorldType.FLAT)
{
if(classesList.contains(biome))
{
if(random.nextInt(chance) == 0)
{
generator.generate(world, random, pos);
}
}
}
}
//计算生成高度 [0,255]层之间可生成 其余忽略
private static int calculateGenerationHeight(World world, int x, int z, Block topBlock) {
int y = world.getHeight();
boolean foundGround = false;
while(!foundGround && y-- >= 0)
{
Block block = world.getBlockState(new BlockPos(x,y,z)).getBlock();
foundGround = block == topBlock;
}
return y;
}
}
4. 在 Main.java中添加建筑生成语句:
@EventHandler
public static void PreInit(FMLPreInitializationEvent event)
{
RegistryHandler.preInitRegistries( );
GameRegistry.registerWorldGenerator(new ModWorldGen(), 3);
//新增建筑生成语句
GameRegistry.registerWorldGenerator(new ModWorldGenCustomStructure(), 0);
}
5.保存所有文件 -> 进入游戏进行建筑制作
可以在超平坦世界进行建造,建筑物建好之后要将建筑物与地面分离,也就是将建筑物下面的一层草方块全部挖空。
输入指令
/give Player minecraft:structure_block
这个名称是你进入游戏时的随机玩家名称,可在eclipse中看到:
6.点击建筑方块,设置相对定位(第一行)和建筑的大小(长宽高),调整建筑空间。
当我们的建筑正好被建筑空间包裹时,说明我们的大小已经设置好了 -> 点击保存 -> 退出游戏
7. 在 run\saves\你的世界名\structures 文档中找到 我们的 建筑.nbt文件并复制
在 resource 包中新建 structures 包,将 .nbt文件放入包中
8.保存所有代码 -> 进入游戏 -> 新建一个世界
我们将生产概率调成50,地形调为平原,在草方块上生成
lol
orz
nb