%%%------------------------------------------------------------------- %%% @author DY %%% @copyright (C) 2020, %%% @doc %%% 游戏进程 %%% @end %%%------------------------------------------------------------------- -module(game_process). -behaviour(gen_server). -include("example.hrl"). -export([start_link/0]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2]). -define(SERVER, ?MODULE). %%%=================================================================== %%% Spawning and gen_server implementation %%%=================================================================== start_link() -> gen_server:start_link(?MODULE, [], []). init([]) -> {TitleMaps, TreeMaps, TreeNodeMaps} = eBhv3:load_tree_file("examples/example.json"), ZombieList = [ %% <<"HUNTER"/utf8>>, %% <<"BOMMER"/utf8>>, %% <<"JOCKEY"/utf8>>, %% <<"SOMKER"/utf8>>, %% <<"SPITTER"/utf8>>, %% <<"CHARGER"/utf8>>, %% <<"TANK"/utf8>>, <<"WITCH"/utf8>> ], init_zombie(ZombieList, TitleMaps, TreeMaps, TreeNodeMaps), UID = <<"凯恩"/utf8>>, init_patrol(UID, TitleMaps, TreeMaps, TreeNodeMaps), erlang:put(uid_list, ZombieList ++ [UID]), self() ! run, {ok, #{frame => 1}}. handle_call(_Request, _From, State) -> {reply, ok, State}. handle_cast(_Request, State) -> {noreply, State}. handle_info(run, #{frame := Frame} = State) -> try ?INFO("第~w分钟", [Frame]), Fun = fun(UID) -> run(UID) end, lists:foreach(Fun, get(uid_list)), erlang:send_after(1000, self(), run), {noreply, State#{frame := Frame + 1}} catch Error:Reason:StackTrace -> ?INFO("Error:~w Reason:~w ~n StackTrace:~p", [Error, Reason, StackTrace]), {stop, normal, State} end; handle_info(finish, State) -> {stop, normal, State}; handle_info({died, UID}, State) -> erlang:put(uid_list, lists:delete(UID, erlang:get(uid_list))), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%%=================================================================== %%% Internal functions %%%=================================================================== new_state(UID, Type, CurGrid) -> case Type of ?HUMAN -> Power = ?MAX_POWER; ?ZOMBIE -> Power = ?RAND(?MAX_POWER div 2, ?MAX_POWER) end, State = #{ uid => UID, type => Type, cur_state => ?STATE_TYPE_IDLE, cur_power => Power, cur_rage => 0, grid_list => [], cur_grid => CurGrid, rival_list => [], misc => #{} }, ?INFO("生成单位:~tp", [State]), State. init_zombie([UID | T], TitleMaps, TreeMaps, TreeNodeMaps) -> {ok, InitiativeBTreeID} = eBhv3:init_btree_by_title(<<"丧尸主动AI"/utf8>>, TitleMaps, TreeMaps, TreeNodeMaps), {ok, PassivityBTreeID} = eBhv3:init_btree_by_title(<<"丧尸被动AI"/utf8>>, TitleMaps, TreeMaps, TreeNodeMaps), game_dict:put_initiative_btree_id(UID, InitiativeBTreeID), game_dict:put_passivity_btree_id(UID, PassivityBTreeID), Grid = {?RAND(0, ?MAX_X), ?RAND(0, ?MAX_Y)}, game_dict:put_role_state(UID, new_state(UID, ?ZOMBIE, Grid)), init_zombie(T, TitleMaps, TreeMaps, TreeNodeMaps); init_zombie([], _TitleMaps, _TreeMaps, _TreeNodeMaps) -> ok. init_patrol(UID, TitleMaps, TreeMaps, TreeNodeMaps) -> {ok, InitiativeBTreeID} = eBhv3:init_btree_by_title(<<"巡逻兵主动AI"/utf8>>, TitleMaps, TreeMaps, TreeNodeMaps), {ok, PassivityBTreeID} = eBhv3:init_btree_by_title(<<"巡逻兵被动AI"/utf8>>, TitleMaps, TreeMaps, TreeNodeMaps), game_dict:put_initiative_btree_id(UID, InitiativeBTreeID), game_dict:put_passivity_btree_id(UID, PassivityBTreeID), Grid = {?RAND(0, ?MAX_X), ?RAND(0, ?MAX_Y)}, game_dict:put_role_state(UID, new_state(UID, ?HUMAN, Grid)). run(UID) -> BTreeID = game_dict:get_initiative_btree_id(UID), #{cur_state := CurState} = State = game_dict:get_role_state(UID), case ?IS_STATE(?STATE_TYPE_DEAD, CurState) of true -> ok; false -> {_, State1} = eBhv3:execute(BTreeID, State), game_dict:put_role_state(UID, State1) end.