(我blog里的排版稍微好看那么一点点:http://www.cnblogs.com/etflly/p/4262391.html)
重要结论昨天把MC中刷怪的源码过了一遍,主要部分是net.minecraft.world.SpawnerAnimals中的findChunksForSpawning函数。有些刷怪机制还是wiki上没有涉及或描述不准(精)确的。明确刷怪机制对刷怪塔制作还是很有帮助的,这里把刷怪的流程简述一下。
- 怪物、水生、环境生物刷怪为每游戏刻(1/20秒)一次,动物每20s一次。
- 可刷怪区块为距离任一玩家所在区块7个区块之内的区块。(可刷怪区块不等于统计怪物数量的区块)
- 刷怪上限为刷怪单位上限 * 可刷怪区块数 / (17*17),单位上限:怪物70,动物10,环境15,水生5。
- 对每种生物类型,每个可刷怪区块单独刷怪,都会刷最多3组怪,每组所刷生物相同,每组最多刷4只。一个区块所刷怪物Y坐标相同。
- 玩家半径24米的球内、Spawn Point半径24米的球内不能刷怪。
- 同类型各种生物的刷怪概率是不同的,比如在主世界的大部分生物群系,怪物中女巫的刷怪概率最低,动物中牛的刷怪概率最低。
- 露天区域怪物刷出会相对稀少。
- 虽然亮度小于等于7时均可刷出怪物,但亮度越低概率越大。
- 刷怪塔的刷怪区域位置的方块最高高度(即对一个(x,z)来说,存在方块的最大的y)越低,刷怪越频繁。降低刷怪塔的高度(不是说层数)这比提高挂机点高度更有效,提高挂机点高度只可以把过低的位置的怪despawn掉,怪物仍会在低处生成,会占用刷怪塔的刷怪概率;但是降低刷怪塔高度可以直接提高怪物刷在塔内的概率。
- 豹猫在怪物刷怪循环中刷怪,但计入动物数量。
- 只有橡木林和针叶林才能刷狼。
- 史莱姆在游戏中满月时生成概率最高而在月朔时不能刷出。
- 蝙蝠在现实时间10月20日~11月5日时刷出更频繁且刷出亮度要求更低,应该是为了迎合万圣节气氛。
刷怪机制
- findChunksForSpawning在每个游戏刻运行一次,其参数是(WorldServer world, boolean spawnHostileMobs, boolean spawnPeacefulMobs, boolean isAnimaltick),world不需多说,spawnHostileMobs表示是否生成攻击性生物,spawnPeacefulMobs表示是否生成和平生物,isAnimaltick表示这个tick(游戏刻)是否应该生成动物。其中isAnimaltick的算法是在游戏的总时间 % 400 == 0,即20s一次
- 如果spawnHostileMobs和spawnPeacefulMobs均为false,直接退出
- 统计应该刷怪的区块及其数量。即每个玩家(非观察者)所在区块东南西北四个方向各延伸8个区块,共1717区块(不是球形区域),但是边界的区块是只计入刷怪区块个数,并不会进行刷怪的*。当多个玩家的刷怪区块重叠时,重复区块只会记录一次。(这里有一个bug,如果一个玩家的刷怪边界区块在另一个玩家刷怪区块内部,那么这个区块会在计算区块数时被统计两次,会使刷怪上限不准确,不过刷怪时还是只会对这个区块刷一次,所以影响不是特别大)
- 对每一种生物类型(怪物、动物、水生、环境):如果当前类型可以刷(取决于spawnHostileMobs, spawnPeacefulMobs,isAnimaltick三个参数),则进行一次刷怪循环(5 - 12)。(这里有一个非常严重的bug,豹猫的生成在怪物的刷怪循环里! ,见附2)
- 计算刷怪上限和已有怪物数量。实际刷怪上限为刷怪单位上限(见**附1**) * 刷怪区块数 / (17*17)。怪物数量统计的部分还没看(TODO),根据已有说法,应该是已加载区块中生物总数,具体生物类型见附1。如果已经到达刷怪上限,则退出本次刷怪循环。
- 对每一个刷怪区块进行一次区块刷怪(7 - 12)。
- 在区块中随机选取一个中心方块,先随机选X,Z,之后选Y,Y不会高于当前(X,Z)的最高值+16(即高度上没有和玩家的距离限制,不过离玩家过远的刷出后会直接despawn)。如果选中的方块是一个NormalCube(见附5),则放弃在此区块刷怪,否则进行3次刷怪(8 - 12),每次只刷一种生物。
- 每次刷怪的初始化工作:将刷怪坐标(x,y,z)初始化为中心方块,重置要刷出的生物。然后进行4次刷怪尝试(9 - 12)。
- 每次刷怪尝试的初始化工作:将现在的刷怪坐标(x,y,z)的x,z坐标随机加减0~5(4次最多加减20,事实上是可能超出当前区块的),如果当前位置半径24米的球内有玩家(非观察者)或spawn point,放弃本次刷怪尝试进行下一次。
- 如果还没有确定本次刷怪的怪物,则根据当前坐标可以刷出的怪物,随机确定一个,随机算法为权值随机。具体每种生物群系(建筑)可刷怪物及其权值见附2。
- 如果当前位置允许刷出这种怪物,且当前位置满足生物刷怪要求(见附3),则将怪物刷出。
- 判断此种生物在当前区块是否已达到上限(见附4),若是,则退出本次区块刷怪(不会再去进行本区块其他生物的刷怪)。
附1. 怪物类型及刷怪单位上限(17 * 17为单位)
注2:骑士生物(如僵尸鸡骑士)的坐骑也算作单独的生物
- 怪物:上限70(骷髅,僵尸,巨人僵尸,蜘蛛,洞穴蜘蛛,爬行者,女巫,史莱姆,蠹虫,恶魂,岩浆怪,僵尸猪人,烈焰人,凋灵骷髅,末影螨,末影人,守卫者,远古守卫者,龙,凋零)
- 动物:上限10(鸡,牛,哞菇,豹猫,猪,兔子,羊,狼,马)
- 环境:上限15(蝙蝠)
- 水生:上限5(鱿鱼)
附2. 每种生物群系(建筑)可刷怪物及其权值
主世界
- 基础刷怪: 峭壁(Extreme Hills),峭壁 M(Extreme Hills M),悬崖(Extreme Hills Edge),桦木森林(Birch Forest),桦木森林山丘(Birch Forest Hills),桦木森林M(Birch Forest M),桦木森林山丘 M(Birch Forest Hills M),黑森林(Roofed Forest),黑森林 M(Roofed Forest M),峭壁+(Extreme Hills+),峭壁+ M(Extreme Hills+ M)
怪物:蜘蛛(100),僵尸(100),骷髅(100),爬行者(100),史莱姆(100),末影人(10),女巫(5)
动物:羊(12),兔子(10),猪(10),鸡(10),牛(8)
水生:鱿鱼(10)
环境:蝙蝠(10) - 森林(Forest),森林山丘(Foreset Hills)
动物:增加狼(5) - 针叶林(Taiga),针叶林 M(Taiga M),针叶林山丘(TaigaHills),冷针叶林(Cold Taiga),冷针叶林 M(Cold Taiga M),冷针叶林山丘(Cold Taiga Hills),大型针叶林(Mega Taiga),红木森林(Mega Spruce Taiga),大型针叶林山丘(Mega Taiga Hills),红木山丘(Mega Spruce Taiga Hills)
动物:增加狼(8) - 丛林(Jungle),丛林 M(Jungle M),丛林山丘(JuncleHills)
怪物:增加豹猫(2)
动物:增加鸡(10) - 丛林边缘(Jungle Edge),丛林边缘 M(JungleEdge M)
动物:增加鸡 - 平原(Plains),向日葵草原(Sunflower Plains)
动物:增加马(5) - 热带草原(Savanna),热带草原 M(Savanna M),热带高原(Savanna Plateau),热带高原 M(Savanna Plateau M)
动物:增加马(1) - 蘑菇岛(MushroomIsland),蘑菇岛岸(MushroomIslandShore)
动物:只有哞菇(8)
其他:清空 - 沼泽(swampland),沼泽 M(Swampland M)
怪物:增加史莱姆(1) - 沙滩(Beach),寒冷沙滩(Cold Beach),沙漠(Desert),沙漠 M(Desert M),沙漠山丘(DesertHills),平顶山(Mesa),平顶山(岩柱)(Mesa (Bryce)),平顶山高原 F(Mesa Plateau F),平顶山高原 F M(Mesa Plateau F M),平顶山高原(Mesa Plateau),平顶山高原 M(Mesa Plateau M),海洋(Ocean),冻洋(FrozenOcean),深海(Deep Ocean),河流(River),冻河(FrozenRiver),石滩(Stone Beach),冻原(Ice Plains),冰刺平原(Ice Plains Spikes),雪山(Ice Mountains)
动物:清空 - 沼泽小屋(SwampHut)
怪物:只有女巫(1)
其他:同所在生物群系 - 海底遗迹(OceanMonument)
怪物:只有守卫者(1)
其他:同所在生物群系
- 一般
怪物:恶魂(50),僵尸猪人(100),岩浆怪(1)
其他:无 - 下界要塞(Nether Fortress)
怪物:烈焰人(10),僵尸猪人(5),骷髅(10),岩浆怪(3)
下界要塞的判断条件有点复杂,用了2种判断,可以看出有一种需要判断脚底方块为地狱砖。具体以后再看TODO
- 怪物:末影人(10)
其他:无
附3. 各种生物刷怪要求
- 鱿鱼和守卫者:当前方块是液体,脚下方块是液体,头顶方块不是NormalCube;碰撞箱内没有其他生物或者船、矿车、末影水晶、点燃的TNT、下落的方块,怪物碰撞箱不和方块有冲突(这段还没太看明白TODO)。
- 其他:脚下方块有完整的上表面,且不是基岩、屏障;当前方块不是NormalCube且不是液体;头顶方块不是NormalCube;碰撞箱内没有其他生物或者船、矿车、末影水晶、点燃的TNT、下落的方块,怪物碰撞箱不和方块有冲突(这段还没太看明白TODO),且碰撞箱内无液体。
- 怪物一般条件(下文列出但没有说明需要满足此条件的怪物则不需要满足):难度不为和平,天空光照不大于0~31随机数字,亮度(打雷时计算这个亮度时来自天空的亮度-10)不大于随机的0~7随机数字。
- 动物一般生成条件:亮度>8,脚下方块为草方块。
- 豹猫:高度不低于63,脚下方块必须是草或者树叶,1/3概率生成失败。
- 蠹虫:需要满足怪物一般条件,半径5的球内必须没有玩家
- 末影螨:需要满足怪物一般条件,半径5的球内必须没有玩家
- 史莱姆:难度不为和平。如果在沼泽,高度在大于50小于70,亮度不大于0~7之间的随机数,随机一个0~1的实数小于当前月亮的月相(盈亏,0~1之间实数,满月为1朔月为0),有1/2概率失败;若不在沼泽,需要是史莱姆区块且高度小于40。
- 恶魂:难度不为和平,只有1/20的概率生成成功
- 岩浆怪:难度不为和平
- 僵尸猪人:难度不为和平
- 守卫者:需要满足怪物一般条件。如果能直视天空(当前方块和天空之间没有非透明方块阻挡)则只有1/20的概率生成成功。
- 鱿鱼:高度大于45小于63
- 蝙蝠:高度小于63,随机一个0~3的数字,如果小于当前亮度则可以生成,有一半几率生成失败;10月20日~11月5日(万圣节?)变为,高度小于63,随机0~6数字,如果小于当前亮度则可以生成,无额外失败概率。
附4. 每种生物单个区块刷怪上限
马:6
恶魂:1
其他:4
附5. NormalCube定义及列表