英雄遠征Erlang原始碼分析(9) 戰鬥流程解析

2021-09-12 17:26:11 字數 4088 閱讀 4885

和戰鬥相關的模組有mod_battle.erl

當玩家程序和怪物程序被建立的時候都會通過mod_battle:start_link()建立乙個戰鬥程序。

該戰鬥程序的state,用於儲存玩家上次出手或者使用技能的時機,用於cd的判斷

-record(state, ]

}).

開始戰鬥的時候,生成攻擊方和防守方的#battle_status記錄例項,戰鬥中的傷害通過這兩個記錄例項來計算

戰鬥存在三種情況:玩家打怪,怪打玩家,玩家打玩家

戰鬥的大致流程:

攻擊方指定防守方id,指定使用的技能id,向伺服器傳送攻擊請求(20001,20003)

進入攻擊方的戰鬥程序內,通過ets獲取防守方資訊,進行攻擊距離,cd,技能配置等檢查

檢查通過,計算雙方持續效果buff,計算技能buff,計算傷害

更新持續buff列表,給防守方玩家(怪物)程序傳送訊息(hp,mp,座標變換),更新雙方狀態,回寫ets,給客戶端廣播戰鬥結果

**流程:

mod_battle:battle(pid, data) ->        發到戰鬥程序處理

start([aer,der,skillid,state]) ->          初始化雙方#battle_status

attack([aer1,der1,skillid],[aer,state]) ->        判斷攻擊是否有效,儲存新的攻擊者狀態

skill(aer,der,skillid,skilllv,state) ->               判斷技能cd,距離,群攻單攻

double_active_skill(aer,der,skilldata,state)            群體技能

/single_active_skill(aer,der,skilldata,state)    ->    單體技能

cale_aer/der_last_effect/4    計算自身持續buff

+ cale_active_effect/6          計算技能buff

+ cale_hurt/2                        計算傷害

具體戰鬥流程:

先進行出手頻率檢查:time - state#state.last_attack_time >= aer#player_status.att_speed

出手頻率檢查通過,進入start([aer, der, skillid, state]).

%%開啟乙個戰鬥服務

start([aer, der, skillid, state])->

aer1 = init_data(aer),

der1 = init_data(der),

attack([aer1, der1, skillid], [aer, state]).

將#player_status或者#ets_mon轉換為#battle_status,傳入attack([aer, der, skillid], [aerinit, state])

attack([aer, der, skillid], [aerinit, state])

獲取玩家技能詳細資料,在skill(aer, der, skillid, skilllv, state)中使用技能

技能使用結果分為兩種情況:使用成功和使用失敗

skill(aer, der, skillid, lv, state)

使用主動技能,進行如下幾項判斷:

技能配置是否存在:獲取#ets_skill

技能cd是否已達到:state#state]

玩家mp是否足夠:#ets_skill.data內的

攻擊距離是否足夠:#ets_skill.attarea

主動還是被動技能,被動技能則使用失敗:#ets_skill.type

判斷是群攻還是單攻:#ets_skill.mod,分別呼叫double/single_active_skill/2

single_acvite_skill(aer, der, skilldata, state)

單體攻擊

計算攻擊方原有加成buff:buff:cale_aer_last_effect(aer#battle_status.batle_status, aer, , nowtime)

其中#batle_status.battle_status為的列表結構,k為加成的屬性名稱,v為加成屬性的值,t為加成過期時間,與當前時間比較,如果沒過期則給#battle_status計算加成,如果過期了則把該加成去掉,最後返回乙個#battle_status

防守方加成buff計算同理

之後計算技能加成:cale_active_effect(data , aer1, der1, aer#battle_status.battle_status, der#battle_status.battle_status, time)

其中data為技能效果列表,在#ets_skill.data中,格式為

除了直接加成數值的效果,有一些值得注意的:

drug:加毒,需要定時給防守一方的戰鬥程序傳送訊息,造成持續掉血效果

shield:法盾,持續一定效果,給防禦方的#battle_status.battle_status加效果

last_def_del:持續減防,帶有概率,在加持續效果之前先進行隨機

通過隨機數值判斷是否打退,若打退則返還新的防守方座標[x, y]

計算傷害:將攻擊方和防守方的二級屬性傳入cale_hurt,返還[hpb,mpb,hurt,status]

傷害計算公式:

命中:hit = (0.25 + hita / (hita + dodgeb) * 1.3)

暴擊:crit = crita/(crita + tenb)

基本傷害:att = (atta*atta) div (atta + defb)

最終傷害:沒暴擊trunc(att/3),暴擊trunc(att*(1+critical)/3)

給防禦方傳送戰鬥結果

防禦方是怪物:在怪物程序內接收,修改#ets_mon的hp,mp,x,y並寫回?ets_mon,觸發人物加經驗,任務殺怪,副本殺怪,怪物掉落事件

防禦方是人物:在玩家程序內接收,修改#player_status,如果玩家死亡則觸發死亡事件

生成戰鬥結果:

戰鬥成功:呼叫send_msg,傳送20001協議,將攻擊者新狀態寫回

戰鬥失敗:呼叫battle_fail,傳送20005協議

群攻的情況:double_active_skill(aer,der,skilldata,state)

先計算攻擊方的持續buff效果和技能buff

獲取攻擊者附近的人物和怪:get_user_for_battle和get_mon_for_battle

從?ets_online和?ets_mon中取

其他計算防禦方的buff,計算傷害同單攻

使用輔助技能:use_assist_skill([aer,der,skillid,state])

玩家是否有該技能

技能配置是否存在

判斷技能cd:#ets_skill.cd

判斷mp:從#ets_skill.data中取

判斷釋放目標:#ets_skill.obj,或者傳入的der={}

以自己為目標:

判斷單攻還是群攻:#ets_skill.mod

單攻:single_assist_skill(aer,der,skilldata) 作用於自己

判斷是否持續性型別:#ets_skill.lastime > 0

持續性型別:cale_assist_last_effect,並將新的持續效果傳送給玩家程序並寫回,傳送20006協議

一次性使用型別:cale_assist_one_effect,目前只有加血,將血量寫回玩家程序,傳送20006協議

群攻:double_assist_skill(aer,_der,skilldata),這裡是作用於隊伍成員,從?ets_online中找,其他同單攻

以他人為目標:先用check_attarea/2判斷攻擊距離,之後同上

修改完畢的#player_status.battle_status,通過'battle_status'傳送回玩家程序並寫回

erlang遊戲原始碼 英雄遠征分析

erl p 1024000 k true smp disable name sd2 127.0.0.1 setcookie sd2 mnesia extra db nodes sd1 127.0.0.1 boot start sasl config log s sd gateway start ex...

英雄遠征Erlang原始碼分析(8) 怪物相關

與怪物相關的模組有三個 mod mon create.erl,mod mon active.erl,lib mon.erl mod mon create 建立負責建立怪物的程序,通過mod mon create create mon monid,scene,x,y,type 建立怪物程序 怪物建立程...

英雄遠征Erlang原始碼分析(4) TCP連線處理

在start tcp 0中啟動了sd tcp listener sup監控樹,並掛到sd sup下。其後啟動的程序樹形關係如下 這是遊戲伺服器啟動後使用observer觀察到的遊戲內程序關係圖,0.68.0 為start tcp 0啟動的sd tcp listener sup監控樹,0.70.0 為...