Minecraft 1.12.2模组开发(十四) 建筑生成 (structure generation)

我们今天对 主世界建筑生成进行制作

1.在 util 包中新建 IStructure 接口

cr7.png

在 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 类

cr1.png

在 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 类

cr9.png

在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 ModWorldGenCustomStructure(), 0);
	}

cr3.png

5.保存所有文件 -> 进入游戏进行建筑制作

可以在超平坦世界进行建造,建筑物建好之后要将建筑物与地面分离,也就是将建筑物下面的一层草方块全部挖空。

输入指令

/give Player minecraft:structure_block

在这里插入图片描述

这个名称是你进入游戏时的随机玩家名称,可在eclipse中看到:

cr10.png

6.点击建筑方块,设置相对定位(第一行)和建筑的大小(长宽高),调整建筑空间。

cr8.png

当我们的建筑正好被建筑空间包裹时,说明我们的大小已经设置好了 -> 点击保存(SAVE) -> 退出游戏

cr5.png

7. 在 run\saves\你的世界名\structures 文档中找到 我们的 建筑.nbt文件并复制

c1.png

在 resource 包中新建 structures 包,将 .nbt文件放入包中

8.保存所有代码 -> 进入游戏 -> 新建一个世界

我们将生产概率调成50,地形调为平原,在草方块上生成

cr4.png

在平原上成功找到所设计的建筑物!

Note: Minecraft 全地形一览

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jay_fearless

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值