[MC源碼解讀] [1.8] 刷怪機制


昨天把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次刷怪嘗試

  1. findChunksForSpawning在每個游戲刻運行一次,其參數是(WorldServer world, boolean spawnHostileMobs, boolean spawnPeacefulMobs, boolean isAnimaltick)world不需多說,spawnHostileMobs表示是否生成攻擊性生物,spawnPeacefulMobs表示是否生成和平生物,isAnimaltick表示這個tick(游戲刻)是否應該生成動物。其中isAnimaltick的算法是在游戲的總時間 % 400 == 0,即20s一次
  2. 如果spawnHostileMobsspawnPeacefulMobs均為false,直接退出
  3. 統計應該刷怪的區塊及其數量。即每個玩家(非觀察者)所在區塊東南西北四個方向各延伸8個區塊,共1717區塊(不是球形區域),但是邊界的區塊是只計入刷怪區塊個數,並不會進行刷怪的*。當多個玩家的刷怪區塊重疊時,重復區塊只會記錄一次。(這里有一個bug,如果一個玩家的刷怪邊界區塊在另一個玩家刷怪區塊內部,那么這個區塊會在計算區塊數時被統計兩次,會使刷怪上限不准確,不過刷怪時還是只會對這個區塊刷一次,所以影響不是特別大)
  4. 對每一種生物類型(怪物、動物、水生、環境):如果當前類型可以刷(取決於spawnHostileMobs, spawnPeacefulMobs, isAnimaltick三個參數),則進行一次刷怪循環(5 - 12)。(這里有一個非常嚴重的bug,豹貓的生成在怪物的刷怪循環里! ,見附2
  5. 計算刷怪上限和已有怪物數量。實際刷怪上限為刷怪單位上限(見**附1**) * 刷怪區塊數 / (17*17)。怪物數量統計的部分還沒看(TODO),根據已有說法,應該是已加載區塊中生物總數,具體生物類型見附1。如果已經到達刷怪上限,則退出本次刷怪循環
  6. 對每一個刷怪區塊進行一次區塊刷怪7 - 12)。
  7. 在區塊中隨機選取一個中心方塊,先隨機選X,Z,之后選Y,Y不會高於當前(X,Z)的最高值+16(即高度上沒有和玩家的距離限制,不過離玩家過遠的刷出后會直接despawn)。如果選中的方塊是一個NormalCube(見附5),則放棄在此區塊刷怪,否則進行3刷怪8 - 12),每次只刷一種生物。
  8. 每次刷怪的初始化工作:將刷怪坐標(x,y,z)初始化為中心方塊,重置要刷出的生物。然后進行4次刷怪嘗試9 - 12)。
  9. 每次刷怪嘗試的初始化工作:將現在的刷怪坐標(x,y,z)的x,z坐標隨機加減0~5(4次最多加減20事實上是可能超出當前區塊的),如果當前位置半徑24米的內有玩家(非觀察者)或spawn point,放棄本次刷怪嘗試進行下一次。
  10. 如果還沒有確定本次刷怪的怪物,則根據當前坐標可以刷出的怪物,隨機確定一個,隨機算法為權值隨機。具體每種生物群系(建築)可刷怪物及其權值見附2
  11. 如果當前位置允許刷出這種怪物,且當前位置滿足生物刷怪要求(見附3),則將怪物刷出。
  12. 判斷此種生物在當前區塊是否已達到上限(見附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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM