我们本次对生物在世界生成的机制进行设置
关于生物的制作,请参考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();
}
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.保存设置 -> 进入游戏 -> 创建一超平坦世界