Minecraft 1.12.2模组开发(十六) 生物生成机制

我们本次对生物在世界生成的机制进行设置

关于生物的制作,请参考Minecraft 1.12.2模组开发(七) 创造实体

1. 在 init 包中新建 ModSpawn 类

在ModSpawn.java 中编写代码:
package com.Joy187.newmod.init;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.Joy187.newmod.entity.EntityEMoLieShou;
import com.Joy187.newmod.entity.EntityRA3;
import com.Joy187.newmod.entity.EntityZZTuFu;

import net.minecraftforge.common.BiomeDictionary.Type;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.EntityLiving;
import net.minecraft.world.biome.Biome;
import net.minecraftforge.common.BiomeDictionary;

public class ModSpawn {
	
	/** Register Mobs based on Biome sub Types */
	public static void registerSpawnList()
	{
		Map<Type, Set<Biome>> biomeMap = buildBiomeListByType() ;
		addNormalSpawn(biomeMap);
		addHumidSpawn(biomeMap);
		addOpenGroundSpawn(biomeMap);
	}
	
	//Mob 添加生物生成信息
	public static void add(Biome biome, int weight, Class<? extends EntityLiving> entityclassIn, int groupCountMin, int groupCountMax) {
			if (weight > 0){
				biome.getSpawnableList(EnumCreatureType.MONSTER).add(new Biome.SpawnListEntry(entityclassIn, weight, groupCountMin, groupCountMax));
			}
	}
    
    //构建模组中生物生成的信息表
	private static Map<Type,Set<Biome>> buildBiomeListByType() {
		Map<Type,Set<Biome>> biomesAndTypes = new HashMap<>();
		
		for (Biome biome: Biome.REGISTRY) {
			Set<BiomeDictionary.Type> types = BiomeDictionary.getTypes(biome);
			
			for (BiomeDictionary.Type type : types) {
				if (!biomesAndTypes.containsKey(type)) {
					biomesAndTypes.put(type,new HashSet<>());
				}
				
				biomesAndTypes.get(type).add(biome);
			}
		}
		return biomesAndTypes;
	}
	
    //添加生物生成信息(最经常用)
	private static void addNormalSpawn(Map<Type, Set<Biome>> biomeMap) {
		for (Biome biome:Biome.REGISTRY) {
			//Example Spawn
			// add (biome,ModConfig. SPAWN_CONF.SPAWN_TAINTER,EntityMoroonTainter. class,1,4);
			//生物在什么地形上生成,生成相关配置(生成率,数值越大越好),生物.class文件, 一次生成最少数量,  最大数量
			add(biome, 2000, EntityRA3.class, 1, 4);
			//为了方便演示,我们调成200,实际值调在(1~10)即可
		}
	}
		
		
	//在开放地块生成生物
	private static void addOpenGroundSpawn (Map<Type, Set<Biome>> biomeMap){
		for(Biome biome : Biome.REGISTRY) {
		//if (!BiomeDictionary.hasType(biome,Type. DENSE))
		//add (biome, ModConfig.SPAWN_CONF.SPAWN_SKELETON_TOWER,EntitySpawnTower.class,1,1);
		}
	}
	
	//在潮湿地块生成(一般不用)
	private static void addHumidSpawn (Map<Type,Set<Biome>>biomeMap) {
		for (Biome biome : Biome.REGISTRY){
			if(BiomeDictionary.hasType(biome, Type.WET) || (BiomeDictionary. hasType(biome, Type.WATER))) {
				//add (biome,ModConfig.SPAWN_CONF. SPAWN_TIDE_MAKER,EntityMoroonTideMaker.class,1,1);
			}
		}
	}
	
	public static void add(int weight, Class<? extends EntityLiving> entityclassIn, int groupCountMin, int groupCountMax, Biome biome) {
			if (weight > 0){
				biome.getSpawnableList(EnumCreatureType.MONSTER).add(new Biome.SpawnListEntry(entityclassIn, weight, groupCountMin, groupCountMax));
			}
	}
}

2. 在 Main.java中添加生物生成的注册信息

修改 Init 函数
	@EventHandler
	public static void Init(FMLInitializationEvent event)
	{
		ModRecipes.init();
		//添加注册信息
		ModSpawn.registerSpawnList();
	}

cr1.png

3. 我们可以修改怪物生成信息

ctrl + 左键进入到继承父类的怪物那里,找到onInitialSpawn()函数,自行进行修改

Zombie的onInitialSpawn()信息

    @Nullable
    public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata)
    {
        livingdata = super.onInitialSpawn(difficulty, livingdata);
        float f = difficulty.getClampedAdditionalDifficulty();
        this.setCanPickUpLoot(this.rand.nextFloat() < 0.55F * f);
        
        //可以自行设置是否生成僵尸宝宝
        if (livingdata == null)
        {
            livingdata = new EntityZombie.GroupData(this.world.rand.nextFloat() < net.minecraftforge.common.ForgeModContainer.zombieBabyChance);
        }

        if (livingdata instanceof EntityZombie.GroupData)
        {
            EntityZombie.GroupData entityzombie$groupdata = (EntityZombie.GroupData)livingdata;

            if (entityzombie$groupdata.isChild)
            {
                this.setChild(true);

                if ((double)this.world.rand.nextFloat() < 0.05D)
                {
                    List<EntityChicken> list = this.world.<EntityChicken>getEntitiesWithinAABB(EntityChicken.class, this.getEntityBoundingBox().grow(5.0D, 3.0D, 5.0D), EntitySelectors.IS_STANDALONE);

                    if (!list.isEmpty())
                    {
                        EntityChicken entitychicken = list.get(0);
                        entitychicken.setChickenJockey(true);
                        this.startRiding(entitychicken);
                    }
                }
                else if ((double)this.world.rand.nextFloat() < 0.05D)
                {
                    EntityChicken entitychicken1 = new EntityChicken(this.world);
                    entitychicken1.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F);
                    entitychicken1.onInitialSpawn(difficulty, (IEntityLivingData)null);
                    entitychicken1.setChickenJockey(true);
                    this.world.spawnEntity(entitychicken1);
                    this.startRiding(entitychicken1);
                }
            }
        }

        this.setBreakDoorsAItask(this.rand.nextFloat() < f * 0.1F);
        this.setEquipmentBasedOnDifficulty(difficulty);
        this.setEnchantmentBasedOnDifficulty(difficulty);

        if (this.getItemStackFromSlot(EntityEquipmentSlot.HEAD).isEmpty())
        {
            Calendar calendar = this.world.getCurrentDate();

            if (calendar.get(2) + 1 == 10 && calendar.get(5) == 31 && this.rand.nextFloat() < 0.25F)
            {
                this.setItemStackToSlot(EntityEquipmentSlot.HEAD, new ItemStack(this.rand.nextFloat() < 0.1F ? Blocks.LIT_PUMPKIN : Blocks.PUMPKIN));
                this.inventoryArmorDropChances[EntityEquipmentSlot.HEAD.getIndex()] = 0.0F;
            }
        }

        this.getEntityAttribute(SharedMonsterAttributes.KNOCKBACK_RESISTANCE).applyModifier(new AttributeModifier("Random spawn bonus", this.rand.nextDouble() * 0.05000000074505806D, 0));
        double d0 = this.rand.nextDouble() * 1.5D * (double)f;

        if (d0 > 1.0D)
        {
            this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).applyModifier(new AttributeModifier("Random zombie-spawn bonus", d0, 2));
        }

        if (this.rand.nextFloat() < f * 0.05F)
        {
            this.getEntityAttribute(SPAWN_REINFORCEMENTS_CHANCE).applyModifier(new AttributeModifier("Leader zombie bonus", this.rand.nextDouble() * 0.25D + 0.5D, 0));
            this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).applyModifier(new AttributeModifier("Leader zombie bonus", this.rand.nextDouble() * 3.0D + 1.0D, 2));
            this.setBreakDoorsAItask(true);
        }

        return livingdata;
    }

Skeleton的onInitialSpawn 信息

    @Nullable
    public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata)
    {
        IEntityLivingData ientitylivingdata = super.onInitialSpawn(difficulty, livingdata);
        
        //设置生物基础攻击力
        this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(4.0D);
        this.setCombatTask();
        return ientitylivingdata;
    }

4.保存设置 -> 进入游戏 -> 创建一超平坦世界

cr2.png

我们的生物成功地在世界中生成!

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Jay_fearless

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

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

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

打赏作者

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

抵扣说明:

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

余额充值