351 lines
14 KiB
Erlang
351 lines
14 KiB
Erlang
%%----------------------------------------------------
|
|
%% 战场配置数据处理
|
|
%% @author yeahoo2000@gmail.com
|
|
%% @end
|
|
%%----------------------------------------------------
|
|
-module(main).
|
|
-export([
|
|
compile/1
|
|
,gen_lua/0
|
|
]
|
|
).
|
|
-include("common.hrl").
|
|
-include("battle.hrl").
|
|
-define(SRV_PATH, "../../server/src/").
|
|
-define(LUA_PATH, "./lua/").
|
|
-define(ul2b(S), unicode:characters_to_binary(S)).
|
|
-define(ub2l(S), unicode:characters_to_list(S)).
|
|
|
|
%% ----------------------------------------------------
|
|
%% 外部接口
|
|
%% ----------------------------------------------------
|
|
compile(all) ->
|
|
io:setopts([{encoding,unicode}]),
|
|
?P("---------------------------------~n"),
|
|
?P("> 正在编译战场配置数据...~n"),
|
|
?P("---------------------------------~n"),
|
|
List = cfg_file(),
|
|
all(List);
|
|
compile(Name) ->
|
|
Mod = list_to_atom(Name),
|
|
B = Mod:cfg(),
|
|
gen_data(B).
|
|
|
|
%% 生成战场编辑工具lua配置文件
|
|
gen_lua() ->
|
|
io:setopts([{encoding, unicode}]),
|
|
?P("---------------------------------~n"),
|
|
?P("> 正在生成战场编辑工具选项数据...~n"),
|
|
?P("---------------------------------~n"),
|
|
UnitStr = ?S("
|
|
-- ------------------------------------
|
|
-- 战场编辑工具单位选项
|
|
-- ------------------------------------
|
|
BattleCfgUnits = {
|
|
~ts
|
|
}
|
|
", [string:join([?S("\t{name=[[~ts]], desc=[[~ts]]}", [Name,Desc]) || #tpl_unit{name=Name, desc=Desc} <- battle_unit:list()], ",\n")]),
|
|
case file:write_file(lists:concat([?LUA_PATH, "battle_cfg_unit.lua"]), format_str(UnitStr)) of
|
|
ok -> ?P("> battle_cfg_unit.lua~n");
|
|
_Err -> ?P("生成battle_cfg_unit.lua数据时发生异常: ~w~n", [_Err])
|
|
end,
|
|
ValStr = ?S("
|
|
-- ------------------------------------
|
|
-- 战场编辑工具变量选项
|
|
-- ------------------------------------
|
|
BattleCfgVals = {
|
|
~ts
|
|
}
|
|
", [string:join([?S("\t{name=[[~ts]], desc=[[~ts]]}", [Name,Desc]) || #tpl_val{name=Name, desc=Desc} <- battle_val:list()], ",\n")]),
|
|
case file:write_file(lists:concat([?LUA_PATH, "battle_cfg_val.lua"]), format_str(ValStr)) of
|
|
ok -> ?P("> battle_cfg_val.lua~n");
|
|
_Err1 -> ?P("生成battle_cfg_val.lua数据时发生异常: ~w~n", [_Err1])
|
|
end,
|
|
ActStr = ?S("
|
|
-- ------------------------------------
|
|
-- 战场编辑工具动作选项
|
|
-- ------------------------------------
|
|
BattleCfgActs = {
|
|
~ts
|
|
}
|
|
", [string:join([?S("\t{name=[[~ts]], type=[[~w]], desc=[[~ts]]}", [Name, Type,Desc]) || #tpl_act{name=Name, type = Type, desc=Desc} <- battle_act:list()], ",\n")]),
|
|
case file:write_file(lists:concat([?LUA_PATH, "battle_cfg_act.lua"]), format_str(ActStr)) of
|
|
ok -> ?P("> battle_cfg_act.lua~n");
|
|
_Err2 -> ?P("生成battle_cfg_act.lua数据时发生异常: ~w~n", [_Err2])
|
|
end,
|
|
CondStr = ?S("
|
|
-- ------------------------------------
|
|
-- 战场编辑工具条件选项
|
|
-- ------------------------------------
|
|
BattleCfgConds = {
|
|
~ts
|
|
}
|
|
", [string:join([?S("\t{name=[[~ts]], desc=[[~ts]]}", [Name, Desc]) || #tpl_cond{name=Name, desc=Desc} <- battle_cond:list()], ",\n")]),
|
|
case file:write_file(lists:concat([?LUA_PATH, "battle_cfg_cond.lua"]), format_str(CondStr)) of
|
|
ok -> ?P("> battle_cfg_cond.lua~n");
|
|
_Err3 -> ?P("生成battle_cfg_cond.lua数据时发生异常: ~w~n", [_Err3])
|
|
end,
|
|
FunStr = ?S("
|
|
-- ------------------------------------
|
|
-- 战场编辑工具方法选项
|
|
-- ------------------------------------
|
|
BattleCfgFuns = {
|
|
~ts
|
|
}
|
|
", [string:join([?S("\t{name=[[~ts]], ret=[[~w]], label=[[~ts]], desc=[[~ts]]}", [Name, Ret, Label, Desc]) || #tpl_fun{name=Name, return = Ret, label = Label, desc=Desc} <- battle_fun:list()], ",\n")]),
|
|
case file:write_file(lists:concat([?LUA_PATH, "battle_cfg_fun.lua"]), format_str(FunStr)) of
|
|
ok -> ?P("> battle_cfg_fun.lua~n");
|
|
_Err4 -> ?P("生成battle_cfg_fun.lua数据时发生异常: ~w~n", [_Err4])
|
|
end,
|
|
KVStr = ?S("
|
|
-- ------------------------------------
|
|
-- 战场编辑工具方法选项
|
|
-- ------------------------------------
|
|
BattleCfgKvs = {
|
|
~ts
|
|
}
|
|
", [string:join([?S("\t~s={~ts}", [Name, string:join([?S("[[~ts]]", [K]) || {K,_V}<-L1], ", ")]) || {Name, L1} <- battle_kv:list()], ",\n")]),
|
|
case file:write_file(lists:concat([?LUA_PATH, "battle_cfg_kv.lua"]), format_str(KVStr)) of
|
|
ok -> ?P("> battle_cfg_kv.lua~n");
|
|
_Err5 -> ?P("生成battle_cfg_kv.lua数据时发生异常: ~w~n", [_Err5])
|
|
end,
|
|
EvtStr = ?S("
|
|
-- ------------------------------------
|
|
-- 战场编辑工具方法选项
|
|
-- ------------------------------------
|
|
BattleCfgEvts = {
|
|
~ts
|
|
}
|
|
", [string:join([?S("\t{name=[[~ts]], desc=[[~ts]]}", [Name, Desc]) || #tpl_evt{name=Name, desc=Desc} <- battle_evt:list()], ",\n")]),
|
|
case file:write_file(lists:concat([?LUA_PATH, "battle_cfg_evt.lua"]), format_str(EvtStr)) of
|
|
ok -> ?P("> battle_cfg_evt.lua~n");
|
|
_Err6 -> ?P("生成battle_cfg_evt.lua数据时发生异常: ~w~n", [_Err6])
|
|
end,
|
|
ok.
|
|
format_str(Str) ->
|
|
unicode:characters_to_binary(Str).
|
|
|
|
%% ----------------------------------------------------
|
|
%% 私有函数
|
|
%% ----------------------------------------------------
|
|
|
|
%% 处理所有配置文件
|
|
all([]) -> ok;
|
|
all([H | T]) ->
|
|
compile(H),
|
|
all(T).
|
|
|
|
%% 生成数据文件
|
|
gen_data(#battle_base{id = Id, name = Mod, type = Type, map = Map, unit = Unit, point = Point, region = Region, global = Global, trigger = L, enter_point = EnterPoint = {MapId,_,_}, combat_launcher = CombatLauncher}) ->
|
|
Tri = gen_trigger(L, []),
|
|
Vars = [
|
|
{description, "描述文字"}
|
|
%% ,{cfg, util:tuplelist_to_record_string(?record_to_tuplelist(battle, Cfg))}
|
|
,{id, Id}
|
|
,{name, Mod}
|
|
,{type, Type}
|
|
,{enter_point, util:to_string(EnterPoint)}
|
|
,{map, util:to_string([MapId | lists:delete(MapId, Map)])}
|
|
,{unit, gen_unit(Unit)}
|
|
,{point, util:to_string(Point)}
|
|
,{region, util:to_string(Region)}
|
|
,{global, gen_val(Global)}
|
|
,{battle_trigger, do_trigger(L, [])}
|
|
,{mod_name, Mod}
|
|
,{trigger, Tri}
|
|
,{combat_launcher, CombatLauncher}
|
|
],
|
|
%% Text = binary_to_list(unicode:characters_to_binary(util:template("./tpl/battle_data.tpl.erl", Vars))),
|
|
Text = unicode:characters_to_binary(util:template("./tpl/battle_data.tpl.erl", Vars)),
|
|
Path = lists:concat([?SRV_PATH, "mod/battle_data/", Mod, ".erl"]),
|
|
%% ?P("====~s ~w~n", [Path, Text]),
|
|
case file:write_file(Path, Text) of
|
|
ok -> ?P("> ~ts.erl~n", [Mod]);
|
|
Err -> ?P("生成战场配置数据[~ts]时发生异常: ~w~n", [Mod, Err])
|
|
end.
|
|
|
|
%% 处理trigger数据
|
|
do_trigger([], Rtn) ->
|
|
"[\n" ++ string:join(lists:reverse(Rtn), ",\n") ++ "\n ]";
|
|
do_trigger([#battle_trigger{name = Name, status = Status, event = Event, vars = Vars, condition = Conds} | T], Rtn) ->
|
|
Cond = gen_cond(Conds),
|
|
Evt = gen_evt(Event),
|
|
S = io_lib:format(" #battle_trigger{name = \"~ts\",status = ~w,event = ~ts,vars = ~w,condition = ~ts}",[Name, to_status(Status), Evt, Vars, Cond]),
|
|
do_trigger(T, [S | Rtn]).
|
|
to_status(1) -> open;
|
|
to_status(0) -> close;
|
|
to_status(S) -> S.
|
|
|
|
gen_unit(Unit) -> "[\n" ++ string:join(make_unit(Unit, []), ",\n ") ++ "\n ]".
|
|
make_unit([], Rtn) -> lists:reverse(Rtn);
|
|
make_unit([#cfg_unit{tpl = Name, cfg = Cfg} | T], Rtn) ->
|
|
case battle_unit:get(Name) of
|
|
{ok, #tpl_unit{code = Code, args = []}} ->
|
|
S = io_lib:format(Code, []),
|
|
make_unit(T, [S | Rtn]);
|
|
{ok, #tpl_unit{code = Code, args = Args}} ->
|
|
GetVal = gen_args(Args, Cfg, unit, []),
|
|
S = io_lib:format(" "++Code, GetVal),
|
|
make_unit(T, [S | Rtn]);
|
|
Reason ->
|
|
?P("查找单位配置模板[~ts]时发生异常: ~w", [Name, Reason]),
|
|
make_unit(T, Rtn)
|
|
end.
|
|
|
|
gen_evt(Event) -> "[" ++ string:join(make_evt(Event, []), ", ") ++ "]".
|
|
make_evt([], Rtn) -> lists:reverse(Rtn);
|
|
make_evt([#cfg_evt{tpl = Name, cfg = Cfg} | T], Rtn) ->
|
|
case battle_evt:get(Name) of
|
|
{ok, #tpl_evt{code = Code, args = []}} ->
|
|
S = io_lib:format(Code, []),
|
|
make_evt(T, [S | Rtn]);
|
|
{ok, #tpl_evt{code = Code, args = Args}} ->
|
|
Args0 = gen_args(Args, Cfg, evt, []),
|
|
S = io_lib:format(Code, Args0),
|
|
make_evt(T, [S | Rtn]);
|
|
Reason ->
|
|
?P("查找事件模板[~ts]时发生异常: ~w~n", [Name, Reason]),
|
|
make_evt(T, Rtn)
|
|
end.
|
|
|
|
gen_val(Event) -> "[\n" ++ string:join(make_val(Event, []), ",\n") ++ "\n ]".
|
|
make_val([], Rtn) -> lists:reverse(Rtn);
|
|
make_val([#cfg_val{tpl = Name, cfg = Cfg} | T], Rtn) ->
|
|
case battle_val:get(Name) of
|
|
{ok, #tpl_val{code = Code, args = []}} ->
|
|
S = io_lib:format(Code, []),
|
|
make_val(T, [S | Rtn]);
|
|
{ok, #tpl_val{code = Code, args = Args}} ->
|
|
GetVal = gen_args(Args, Cfg, val, []),
|
|
S = io_lib:format(" "++Code, GetVal),
|
|
make_val(T, [S | Rtn]);
|
|
Reason ->
|
|
?P("查找事件模板[~ts]时发生异常: ~w~n", [Name, Reason]),
|
|
make_val(T, Rtn)
|
|
end.
|
|
|
|
%% 生成触发器代码
|
|
gen_trigger([], Funs) -> lists:reverse(Funs);
|
|
gen_trigger([#battle_trigger{name = Name, action = Act} | T], Funs) ->
|
|
F = gen_action(Name, Act),
|
|
gen_trigger(T, [F | Funs]).
|
|
|
|
%% 生成action代码
|
|
gen_action(Name, Acts) -> ?S("trigger(\"~ts\") ->\n~ts,\n ok;\n\n", [Name, make_action(Acts, [])]).
|
|
make_action([], Fun) -> string:join(lists:reverse(Fun), ",\n");
|
|
make_action([#cfg_act{tpl = Name, cfg = Cfg} | T], Fun) ->
|
|
case battle_act:get(Name) of
|
|
{error, Reason} -> ?P("查找动作模板[~ts]时发生异常: ~w~n", [Name, Reason]);
|
|
{ok, #tpl_act{code = Code, args = Args}} ->
|
|
Rtn = gen_args(Args, Cfg, act, []),
|
|
case catch io_lib:format(" " ++ Code, Rtn) of
|
|
{'EXIT', _} ->
|
|
?P("处理动作模板[~ts]时发生异常: ~ts 与 ~w 参数不匹配~n", [Name, Code, Rtn]),
|
|
make_action(T, Fun);
|
|
S ->
|
|
make_action(T, [S | Fun])
|
|
end
|
|
end.
|
|
|
|
%% 获取所有的配置文件
|
|
cfg_file() ->
|
|
case file:list_dir("./cfg") of
|
|
{ok, L} -> do_cfg_file(L, []);
|
|
{error, Why} ->
|
|
?P("获取战场配置文件时发生异常: ~w~n", [Why]),
|
|
[]
|
|
end.
|
|
|
|
%% 返回所有的配置文件
|
|
do_cfg_file([], List) -> List;
|
|
do_cfg_file([F | T], List) ->
|
|
L = case filename:extension(F) =:= ".erl" of
|
|
true ->
|
|
M = filename:basename(filename:rootname(F)),
|
|
[M | List];
|
|
_ -> List
|
|
end,
|
|
do_cfg_file(T, L).
|
|
|
|
gen_cond(Conds) ->
|
|
"[" ++ string:join(make_cond(Conds, []), ", ") ++ "]".
|
|
make_cond([], Conds) ->
|
|
lists:reverse(Conds);
|
|
make_cond([#cfg_cond{tpl = Name, cfg = Cfg} | T], Conds) ->
|
|
case battle_cond:get(Name) of
|
|
{ok, #tpl_cond{code = Code, args = [condition]}} ->
|
|
[{condition, Ncfg}] = Cfg,
|
|
S = io_lib:format(Code, [gen_cond(Ncfg)]),
|
|
make_cond(T, [S | Conds]);
|
|
{ok, #tpl_cond{code = Code, args = Args}} ->
|
|
Rtn = gen_args(Args, Cfg, condition, []),
|
|
S = io_lib:format(Code, Rtn),
|
|
make_cond(T, [S | Conds]);
|
|
Reason ->
|
|
?P("查找条件模板[~ts]时发生异常: ~w~n", [Name, Reason]),
|
|
make_cond(T, Conds)
|
|
end.
|
|
|
|
%% 参数处理
|
|
gen_args([], _, _Type, Args) ->
|
|
lists:reverse(Args);
|
|
gen_args([Key | T], CfgArgs, Type, Args) ->
|
|
case find_args(Key, CfgArgs) of
|
|
Evt = #cfg_evt{} ->
|
|
Rtn = gen_evt([Evt]),
|
|
gen_args(T, CfgArgs, Type, [Rtn | Args]);
|
|
{pos, [Id, X, Y]} ->
|
|
Rtn = io_lib:format("{~w, ~w, ~w}",[Id, X, Y]),
|
|
gen_args(T, CfgArgs, Type, [Rtn | Args]);
|
|
{gvar, GVar} ->
|
|
Rtn = io_lib:format("get({global,~s})",[GVar]),
|
|
gen_args(T, CfgArgs, Type, [Rtn | Args]);
|
|
{action, []} ->
|
|
Rtn = "\tskip",
|
|
gen_args(T, CfgArgs, Type, [Rtn | Args]);
|
|
{action, Acts} when is_list(Acts) ->
|
|
Rtn = make_action(Acts, []),
|
|
gen_args(T, CfgArgs, Type, [Rtn | Args]);
|
|
{condition, Conds} when is_list(Conds) ->
|
|
Rtn = gen_cond(Conds),
|
|
gen_args(T, CfgArgs, Type, [Rtn | Args]);
|
|
{key, KeyName, Val} ->
|
|
case lists:keyfind(Val, 1, battle_kv:get(KeyName)) of
|
|
{_, La} ->
|
|
Rtn = case is_binary(La) of
|
|
true -> io_lib:format("\"~ts\"", [La]);
|
|
false -> util:to_list(La)
|
|
end,
|
|
gen_args(T, CfgArgs, Type, [Rtn | Args]);
|
|
_ -> ?P("查找键值发送错误[~w]~n",[KeyName]),
|
|
gen_args(T, CfgArgs, Type, Args)
|
|
end;
|
|
{func, Fname, CfgArgs0} when is_list(CfgArgs0) ->
|
|
case battle_fun:get(Fname) of
|
|
{error, Reason} ->
|
|
?P("~ts查找事件函数模板[~ts]时发生异常: ~w~n", [Key, Fname, Reason]),
|
|
gen_args(T, CfgArgs, Type, Args);
|
|
{ok, #tpl_fun{code = Code0, mfa_code = MfaCode, args = Args0}} ->
|
|
Rtn = gen_args(Args0, CfgArgs0, func, []),
|
|
Code = case Code0 of
|
|
[_ | _] when Type =:= act orelse MfaCode =:= [] -> Code0;
|
|
_ -> MfaCode
|
|
end,
|
|
case catch io_lib:format(Code, Rtn) of
|
|
{'EXIT', _} ->
|
|
?P("~ts处理事件函数模板[~ts]时发生异常: ~ts 与 ~w 参数不匹配~n", [Key, Fname, Code, Rtn]),
|
|
gen_args(T, CfgArgs, Type, Args);
|
|
S ->
|
|
gen_args(T, CfgArgs, Type, [S | Args])
|
|
end
|
|
end;
|
|
I ->
|
|
gen_args(T, CfgArgs, Type, [util:to_list(I) | Args])
|
|
end.
|
|
|
|
find_args(Key, Args) ->
|
|
case lists:keyfind(Key,1, Args) of
|
|
{Key, Val} -> Val;
|
|
_ -> ?P("查找不到参数:~w ~n", [Key]), Key
|
|
end.
|