AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

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

作者: 作者的头像   GRID ,  2021-05-25 18:44:42 ,  所有人可见 ,  阅读 1731


3


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

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

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 addC(Class<? extends EntityLiving> entityclassIn,int weight, int groupCountMin, int groupCountMax, Biome biome) {
        if (weight > 0){
            biome.getSpawnableList(EnumCreatureType.CREATURE).add(new Biome.SpawnListEntry(entityclassIn, weight, groupCountMin, groupCountMax));
        }
    }
    //怪物生成
    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

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

0 评论

你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息