狹義來講,技能就是幾個人作戰時,可以對他人使用產生一定效果的操作。魔獸世界對技能定義進行了擴展,即在魔獸世界中,產生一定效果的任何操作都是技能。例如 吃面包,使用物品,采礦,訓練商業技能 等等。
魔獸世界中技能可以產生一個立即的效果(例如 扣血,扣籃,挖到一個礦),或者是一個持續的狀態(buff),或者兩者兼而有之。立即效果處理起來比較簡單這里就不細說了,這里主要說說程序中buff怎樣處理。
魔獸世界中buff簡直是千變萬化,估計沒有人能完全的了解所有的buff的效果。這其中有很多種分類,例如
類型 |
例子 |
影響數值型 |
奧術智慧,邪甲術 |
控制型 |
變羊術 恐懼 |
持續傷害型 |
腐蝕術 |
被動觸發型 |
荊棘術 |
加強效果型 |
法師的沖擊天賦 |
...... |
...... |
很顯然,暴雪的開發人員不可能一個一個技能去編寫。那不僅難以控制代碼,策划也無法脫離程序員去實現技能。其實我們根據破解魔獸世界的客戶端,可以看到,魔獸的技能是一個一個配置出來的!程序員只需要做好基本的效果,之后技能就交給策划去配置了。
咋一看,buff種類太多,看上去讓人頭大。其實可以分解出一個共有的特點:buff是由三個部分組成的: 1. 時間 2. 條件 3. 動作。
我們分析一下上面5種類型的buff這三個特點:
技能 |
時間 |
條件 |
動作 |
奧術智慧 |
加減buff時 |
本次加的buff |
加減智力數值 |
變羊術 |
加減buff時 |
本次加的buff |
變形,減buff 還原 |
腐蝕術 |
該buff時間間隔到的時候 |
扣血 |
|
荊棘術 |
被打時 |
1.近戰攻擊 2.命中 |
對攻擊敵人釋放攻擊技能 |
法師的沖擊天賦 |
打中時 |
1.火焰魔法 2.命中 3. %2 幾率roll成功 |
對目標釋放一個暈技能 |
一個動作可以是具體效果,也可以是釋放一個技能
上面幾個技能觸發時機如下圖所示:
我們可以發現,在整個技能流程中buff作用效果可以穿插在一些時間點。所以我們可以這樣設計配置文件:
技能id |
時間點 |
條件 |
動作 |
奧術智慧id |
1,2 |
5 |
1,2 |
變羊id |
1,2 |
5 |
3,4 |
腐蝕術id |
3 |
5 |
|
荊棘術id |
4 |
1 and 2 |
6 |
沖擊id |
5 |
3 and 2 and 4 |
6 |
這里給出具體含義:
時間點:
1 加buff時
2 減buff時
3 buff tick到時
4 被打時
5 打人時
條件:
1 技能是近戰
2 技能命中
3 技能是火焰魔法
4 幾率roll成功
5 本次技能施放的buff
動作
1 加智力
2 減智力
3 變形
4 變形還原
5 扣血
6 釋放一個技能
時間點的使用
服務器端怎么使用這些配置呢?很簡單,服務器上提供一個鈎子列表即可,配置文件中,時間點就是鈎子的掛載點
vector<boost::signals2::signal>
比如荊棘術buff加上時,根據配置注冊到事件的vector相應位置,下標就是時間點
一旦有人被攻擊,就會執行下標為4 的所有事件
一旦攻擊 就會執行,下標為5的所有事件
條件的擴展
魔獸世界中,buff觸發的條件是極其復雜的。例如上面沖擊天賦觸發條件涉及到三個小條件。這還是比較簡單,條件與條件之間只有and關系。如果有or關系怎么辦?我們可以用一棵行為樹解決這個問題,行為樹可以實現and和or的關系。所以完全可以讓程序員開發策划需要的condition節點,策划使用編輯器編輯行為樹即可。行為樹在此就不細說了,大家可以找google看看
再說天賦成就和LOG系統
看到這里,大家也明白了成就系統無非也是三點1. 時間 2. 條件 3. 動作
比如坐騎成就:
成就id |
時間點 |
條件 |
動作 |
收集50個坐騎 |
收到一個坐騎時 |
有50個坐騎 |
增加一個坐騎大師的稱號 |
LOG也是一樣:
Log |
時間點 |
條件 |
動作 |
記錄一次轉移金幣大於1000G的LOG |
扣錢 |
數量> 1000 |
記錄log |
魔獸世界天賦就是一些隱藏的永久buff
順便給出一個簡單實現:
https://github.com/egametang/Egametang/tree/master/Cpp/Game/BehaviorTree