Files
2026-05-23 22:10:14 +08:00

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.