昨天把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日時刷出更頻繁且刷出亮度要求更低,應該是為了迎合萬聖節氣氛
刷怪機制
注:循環嵌套比較亂,我將幾個循環從大到小定義為刷怪循環
(每種生物類型進行1次),區塊刷怪
(每個可行區塊進行1次),刷怪
(每次區塊刷怪
進行3次,每次刷怪
只會刷一種生物),刷怪嘗試
(每次刷怪
進行4次刷怪嘗試
)
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. 各種生物刷怪要求
方塊及碰撞箱要求
(腳下方塊為當前方塊y坐標-1,頭頂方塊為當前方塊y坐標+1)
魷魚和守衛者:當前方塊是液體,腳下方塊是液體,頭頂方塊不是NormalCube;碰撞箱內沒有其他生物或者船、礦車、末影水晶、點燃的TNT、下落的方塊,怪物碰撞箱不和方塊有沖突(這段還沒太看明白TODO)。
其他:腳下方塊有完整的上表面,且不是基岩、屏障;當前方塊不是NormalCube且不是液體;頭頂方塊不是NormalCube;碰撞箱內沒有其他生物或者船、礦車、末影水晶、點燃的TNT、下落的方塊,怪物碰撞箱不和方塊有沖突(這段還沒太看明白TODO),且碰撞箱內無液體。
其他條件
- 怪物一般條件(下文列出但沒有說明需要滿足此條件的怪物則不需要滿足):難度不為和平,天空光照不大於031隨機數字,亮度(打雷時計算這個亮度時來自天空的亮度-10)不大於隨機的07隨機數字。
- 動物一般生成條件:亮度>8,腳下方塊為草方塊。
- 豹貓:高度不低於63,腳下方塊必須是草或者樹葉,1/3概率生成失敗。
- 蠹蟲:需要滿足怪物一般條件,半徑5的球內必須沒有玩家
- 末影蟎:需要滿足怪物一般條件,半徑5的球內必須沒有玩家
- 史萊姆:難度不為和平。如果在沼澤,高度在大於50小於70,亮度不大於07之間的隨機數,隨機一個01的實數小於當前月亮的月相(盈虧,0~1之間實數,滿月為1朔月為0),有1/2概率失敗;若不在沼澤,需要是史萊姆區塊且高度小於40。
- 惡魂:難度不為和平,只有1/20的概率生成成功
- 岩漿怪:難度不為和平
- 僵屍豬人:難度不為和平
- 守衛者:需要滿足怪物一般條件。如果能直視天空(當前方塊和天空之間沒有非透明方塊阻擋)則只有1/20的概率生成成功。
- 魷魚:高度大於45小於63
- 蝙蝠:高度小於63,隨機一個03的數字,如果小於當前亮度則可以生成,有一半幾率生成失敗;10月20日11月5日(萬聖節?)變為,高度小於63,隨機0~6數字,如果小於當前亮度則可以生成,無額外失敗概率。
附4. 每種生物單個區塊刷怪上限
狼:8
馬:6
惡魂:1
其他:4
附5. NormalCube
定義及列表
TODO