【MJ相關(guān)研究】你渾身上下都是破綻!
真理往往是簡單的。當(dāng)你發(fā)現(xiàn)它后,會大呼寶開SB。

寫在前面
本文是對最近舞王以及伴舞幾個bug的研究小結(jié)。以下所有結(jié)論皆已用高精度工具驗(yàn)證,但無代碼層支持,請辯證性看待,勿輕信。

正文
幾個常識:
1. 目前來看,上下前后左右伴舞毫無區(qū)別。棧位理論在這里沒有任何貢獻(xiàn)。
2. 舞王和伴舞各自有不同的bug,不可混為一談,但究其原理是相通的。
3. IZE有一個特性叫速度重置。剛出生的僵尸若500cs內(nèi)不受攻擊,進(jìn)入速度重置,每一幀都隨機(jī)重置速度;受過攻擊的僵尸若525cs內(nèi)不受攻擊,也進(jìn)入速度重置。處于速度重置狀態(tài)的僵尸受攻擊后該狀態(tài)立刻解除,速度固定為受攻擊這一幀隨機(jī)重置到的速度。
先說下對兩者都適用的【速度刷新】機(jī)制。
滿足以下任意條件時,觸發(fā)舞王/伴舞的速度刷新:
① 處于踏步相位(且自身不在啃食狀態(tài));
② 處于速度重置狀態(tài);
③ 啃食完畢任意植物;
④ (伴舞限定)首次出土完畢的瞬間,且此時沒有任何隊(duì)友卡位。
注意:④和①~③略有不同,是唯一一個要求隊(duì)友不卡位的。
這個速度刷新有什么用呢?
比如舞王本體原速,但有伴舞被減速時,舞王和其他伴舞從原速變?yōu)闇p速的判定,是包含在速度刷新里的。類似地,伴舞從減速變回原速也是一樣的道理。

舞王有一個特殊bug是【抽風(fēng)】,具體表現(xiàn)為腳步動畫加速(幀速*2),前進(jìn)速度翻倍。抽風(fēng)的判定點(diǎn)是舞王每次召喚后第一次進(jìn)入前進(jìn)動畫的瞬間。舞王所處位置沒有植物的話,就是召喚后200cs;否則是舞王啃完該植物的瞬間。此時,若有任意伴舞在啃食任意植物,舞王就會進(jìn)入抽風(fēng)狀態(tài),直到速度刷新。
抽風(fēng)狀態(tài)是持續(xù)有效的(直至速度刷新為止)。抽風(fēng)的舞王只要不被伴舞卡位,就會加速前進(jìn)。伴舞怎么死的不重要,被大嘴花吃掉乃至被冰豆打死都無所謂,隔了多久被打死也無所謂。關(guān)鍵是期間不能觸發(fā)舞王的速度刷新。

接下來是伴舞。伴舞除了和舞王通用的【速度刷新】外,還有一套專屬的【初始化】機(jī)制。
滿足以下任意條件,會觸發(fā)伴舞的速度初始化:
①?處于踏步相位(且自身處于非啃食狀態(tài));
②?處于速度重置狀態(tài),且不被隊(duì)友卡位;
③ 啃食完畢任意植物,且不被隊(duì)友卡位;
④ 首次出土完畢的瞬間,且不被隊(duì)友卡位。
①適用于踏步相位,②~④適用于前進(jìn)相位。
誒?好像有點(diǎn)眼熟?沒錯,其實(shí)速度初始化和速度刷新的原理類似,①和④是完全相通的,而②~③繼承自速度刷新,只是附加了其他隊(duì)友不能卡位的條件。
現(xiàn)在讓我們來腦補(bǔ)一下代碼層發(fā)生了什么事。首先,踏步相位進(jìn)行了特殊處理,對全體伴舞進(jìn)行速度刷新,但對正在啃食的僵尸進(jìn)行了特殊處理,跳過刷新。除此之外,速度重置和啃食完畢這兩個事件也進(jìn)行了特殊處理,用于“恢復(fù)速度”。然而,如果其他同伴卡位,那么速度就恢復(fù)成了0。所以此二者也可以理解為是“失敗”的速度刷新。
而至于④,我認(rèn)為是寶開亡羊補(bǔ)牢式的后期處理,下面會詳細(xì)討論。
沒有經(jīng)歷過初始化的伴舞,在前進(jìn)相位時就會發(fā)愣,也就是著名的發(fā)愣bug了。發(fā)愣也是持續(xù)性的,直到伴舞完成速度初始化。
游戲是從每個僵尸出生算起,每隔4cs計(jì)算一次該僵尸的啃食判定。伴舞召喚到出土150cs,但152cs才會檢測啃食,所以中間有2cs的空隙。如果初始相位為踏步,那么在這2cs內(nèi)伴舞就已經(jīng)完成速度初始化了(符合條件①),因此后續(xù)不會發(fā)愣。
對于普通的【大噴 花 花】模型而言,前伴舞會發(fā)愣的間隔只有80cs,這是因?yàn)榈猛瑫r滿足初始相位為前進(jìn)和啃完花后的相位仍為前進(jìn)兩個條件。
理論計(jì)算一下:
從伴舞出生算起,150cs出土完畢,152cs開啃,452cs啃完。在150cs、452cs相位都得是前進(jìn)。那么踏步最晚在451cs結(jié)束,最早可以在153cs開始(先暫時各留了1cs)。按踏步總長230cs算,求得的容差是68cs。
emmm好像和80cs對不上啊。翻這個老貼:https://tieba.baidu.com/f?kz=699121249,發(fā)現(xiàn)一句很神奇的話。
“一個周期長(4.6s±0.005s),包括(2.3s±0.05s)舞蹈(2.3s±0.05s)行走但舞蹈的末尾約0.1s是前進(jìn)性的”
踏步相位末尾0.1s是前進(jìn)性的?嗯?
于是我重新測了一下。逐幀讀取舞王坐標(biāo)及狀態(tài),得到了完整舞蹈周期如下:
44前進(jìn)(240cs)→ 45(20cs) → 47(60cs) → 46(60cs) → 49(60cs) → 48(20cs) → 循環(huán)
其中狀態(tài)44為前進(jìn),狀態(tài)45~49均為踏步(以有無坐標(biāo)變化區(qū)分)。
所以準(zhǔn)確來說,前進(jìn)相位有240cs,而踏步相位是220cs(被分割成了多個狀態(tài))。
回到前面的計(jì)算。用新數(shù)據(jù)的話,容差變?yōu)榱?8cs。和實(shí)際差的2cs,很有可能就是邊界值了。
重新來一遍:假設(shè)152cs開啃的這一幀,相位已經(jīng)可以是踏步了。同時452cs啃完的這一幀,踏步剛剛結(jié)束,也是允許的。這樣踏步最早可在152cs開始,最晚在452cs結(jié)束。踏步總長220cs,因而452 - (152 + 220) = 80cs,分毫不差。

現(xiàn)在還有最后一個問題。有時候上/下伴舞被冰豆打殘打死時,舞王新召喚的前伴舞是個愣在原地不動的!然后喜聞樂見地被小噴干翻了(
結(jié)合上面對發(fā)愣的解釋,這個就很好理解了。眾所周知,除了首次召喚,舞王總是固定在踏步相位的一開始召喚,也就是狀態(tài)45的第一幀。以這一幀為原點(diǎn),42cs后舞王召喚,192cs后伴舞出土,194cs后伴舞開啃。踏步總長度220cs,可見192-193cs期間伴舞的相位必然是踏步,滿足速度初始化的條件②,故不會發(fā)愣。
但是如果MJ被減速,則召喚動作慢一倍,召喚總用時變?yōu)?4cs。那么伴舞就是234cs出土,236cs開啃,踏步狀態(tài)(220cs)已經(jīng)過去了,其初始相位為前進(jìn)!因而像這樣的伴舞就會發(fā)愣。
推論:有伴舞卡位時,減速M(fèi)J召喚的所有伴舞都是發(fā)愣的。伴舞在剛剛出土完畢后會特別進(jìn)行一次判定,但若此時有小隊(duì)成員被卡位,就不滿足④,無法完成速度初始化了。
這其實(shí)就是為什么之前說④是后期亡羊補(bǔ)牢式的處理。如果沒有④,減速舞王召喚的所有伴舞都會直接原地發(fā)愣…… 為了讓舞王行為正常,寶開可能后期補(bǔ)上了伴舞召喚完畢時進(jìn)行速度刷新的邏輯(然后忘了其他成員卡位時,速度刷新會失敗這件事)。

然后說下舞王不召喚這件事。
這個就比較清晰易懂了。用跟上面逐幀讀取舞王內(nèi)存類似的辦法,發(fā)現(xiàn)從舞王進(jìn)入前進(jìn)相位算起,經(jīng)過160cs時會進(jìn)行判定。此時若有任意伴舞消失(視覺上是尸體消亡),舞王就會召喚,否則跳過召喚。
注意:前進(jìn)相位整整有240cs,且如果要召喚,舞王召喚動作本身耗時42cs(減速則84cs)。然而,雖然【是否要召喚】已經(jīng)提前欽定了,具體召喚幾個是看召喚動作完畢時缺少的伴舞數(shù)量?。?/p>
也就說,以前進(jìn)相位的第一幀為原點(diǎn),t=160cs時做出決策是否召喚,但t=282cs時(減速則t=324cs)才會真正判定有幾個伴舞從土里冒出來……真是無力吐槽了。特別是舞王減速時,從【決策】到【生效】差了整整164cs。
原版舞王之所以不漏腦,很大程度上要?dú)w功于走出地圖范圍被程序清理掉的前伴舞。由于檢測到前伴舞空缺,舞王在底線才會持續(xù)召喚,否則就他這判定邏輯,漏個腦太容易了……

最后說說以上結(jié)論可能的應(yīng)用。
舞王抽風(fēng),算是比較容易觸發(fā)了。只要舞王本體不在速度重置里,伴舞出生后團(tuán)滅(或者說不被卡位),舞王就會飛速前進(jìn)。允許女仆的話,甚至可以一直保持這個狀態(tài),直到吃掉腦子hhh。
當(dāng)然,伴舞的死法是有講究的。都被土豆炸死顯然不行,因?yàn)?0cs的那個點(diǎn)必須有伴舞在啃食。大嘴花是一個很好用的介質(zhì),觸發(fā)到生效70cs,那么形似【大嘴 + 某植物】的型就能輕松觸發(fā)抽風(fēng)。這也是為啥平常最常見的抽風(fēng)發(fā)生在即死,舞王過地刺時伴舞被大嘴吃掉,然后舞王加速前進(jìn)。地刺保證了舞王不被速度重置;大嘴保證了伴舞50cs處在啃食,但之后迅速gg不擋路。
關(guān)于發(fā)愣,因?yàn)槠淙莶钍?0cs,那么隨機(jī)丟一個舞王,前伴舞啃完4列后的發(fā)愣概率就是精確的80 / 460 = 17.4%。至于這個數(shù)據(jù)有什么用,就待各位繼續(xù)挖掘了。