%%%-------------------------------------------------------------------
%%% @doc    孩子-辅助模块
%%% Module  : lib_child_util.erl
%%% Created : 2020-02-17
%%% @Author : tyl
%%%-------------------------------------------------------------------
-module(lib_child_util).

-include("common.hrl").
-include("server.hrl").
-include("child.hrl").
-include("goods.hrl").
-include("def_goods.hrl").
-include("def_fun.hrl").
-include("errcode.hrl").

-export([
	check_adopt/1                 %% 孩子领养检查
	,check_grow_up/1              %% 孩子成长检查
	,check_upgrade_link_heart/2   %% 同心度培养检查
	,check_rename/1               %% 孩子改名字检查

	,check_show_off/1             %% 晒娃检查

	,check_active_skill/1         %% 技能激活检查
	,check_upgrade_skill/1        %% 技能升级检查

	,check_active_vehicle/1       %% 载具激活检查
	,check_upgrade_vehicle/1      %% 载具升阶检查

	,check_stren_toy/2            %% 玩具强化检查
	,check_inlay_toy/2            %% 装备玩具检查
	,check_compose_toy/2          %% 合成玩具检查
	,check_draw_out_toy/2         %% 领取玩具检查
	,check_speed_up_forge/2       %% 打造加速检查
	,check_active_toy_slot/2      %% 玩具位开启检查

	,check_active_fashion/1       %% 激活时装检查
	,check_upgrade_fashion/1      %% 升级时装检查
	,check_put_on_fashion/1       %% 穿戴时装检查
	,check_put_off_fashion/1      %% 脱下时装检查

	,check_receive_suit_reward/1  %% 领取玩具套装奖励检查
	,check_active_toy/1           %% 激活玩具检查
	,check_upgrade_toy_box/2      %% 升级玩具盒检查

	,check_task_reward/2          %% 任务阶段奖励检查

	,save_dict_status_child/2
]).

-compile(export_all).

%% ----------------------------------------------------------------------
%% @doc 检查函数
%% ----------------------------------------------------------------------
%% 孩子领养检查
check_adopt([]) -> true;
check_adopt([Check|L]) ->
	case do_check_adopt(Check) of
		true -> check_adopt(L);
		{false, Res} -> {false, Res}
	end.

%% 孩子成长检查
check_grow_up([]) -> true;
check_grow_up([Check|L]) ->
	case do_check_grow_up(Check) of
		true -> check_grow_up(L);
		{false, Res} -> {false, Res}
	end.

%% 同心度培养检查
check_upgrade_link_heart([], Player) -> {true, Player};
check_upgrade_link_heart([Check|L], Player) ->
	case do_check_upgrade_link_heart(Check, Player) of
		{true, NewPlayer} -> check_upgrade_link_heart(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

%% 孩子改名字检查
check_rename([]) -> true;
check_rename([Check|L]) ->
	case do_check_rename(Check) of
		true -> check_rename(L);
		{false, Res} -> {false, Res}
	end.

%% 晒娃检查
check_show_off([]) -> true;
check_show_off([Check|L]) ->
	case do_check_show_off(Check) of
		true -> check_show_off(L);
		{false, Res} -> {false, Res}
	end.

%% 技能激活检查
check_active_skill([]) -> true;
check_active_skill([Check|L]) ->
	case do_check_active_skill(Check) of
		true -> check_active_skill(L);
		{false, Res} -> {false, Res}
	end.

%% 技能升级检查
check_upgrade_skill([]) -> true;
check_upgrade_skill([Check|L]) ->
	case do_check_upgrade_skill(Check) of
		true -> check_upgrade_skill(L);
		{false, Res} -> {false, Res}
	end.

%% 载具激活检查
check_active_vehicle([]) -> true;
check_active_vehicle([Check|L]) ->
	case do_check_active_vehicle(Check) of
		true -> check_active_vehicle(L);
		{false, Res} -> {false, Res}
	end.

%% 载具升阶检查
check_upgrade_vehicle([]) -> true;
check_upgrade_vehicle([Check|L]) ->
	case do_check_upgrade_child_vehicle(Check) of
		true -> check_upgrade_vehicle(L);
		{false, Res} -> {false, Res}
	end.

%% 玩具强化检查
check_stren_toy([], Player) -> {true, Player};
check_stren_toy([Check|L], Player) ->
	case do_check_stren_toy(Check, Player) of
		{true, NewPlayer} -> check_stren_toy(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

%% 装备玩具检查
check_inlay_toy([], Player) -> {true, Player};
check_inlay_toy([Check|L], Player) ->
	case do_check_inlay_toy(Check, Player) of
		{true, NewPlayer} -> check_inlay_toy(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

%% 卸下玩具检查
check_load_off_toy([], Player) -> {true, Player};
check_load_off_toy([Check|L], Player) ->
	case do_check_load_off_toy(Check, Player) of
		{true, NewPlayer} -> check_load_off_toy(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

%% 合成玩具检查
check_compose_toy([], Player) -> {true, Player};
check_compose_toy([Check|L], Player) ->
	case do_check_compose_toy(Check, Player) of
		{true, NewPlayer} -> check_compose_toy(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

%% 分解玩具检查
check_decompose_toy([], Player) -> {true, Player};
check_decompose_toy([Check|L], Player) ->
	case do_check_decompose_toy(Check, Player) of
		{true, NewPlayer} -> check_decompose_toy(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

%% 打造玩具检查
check_forge_toy([], Player) -> {true, Player};
check_forge_toy([Check|L], Player) ->
	case do_check_forge_toy(Check, Player) of
		{true, NewPlayer} -> check_forge_toy(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

%% 领取玩具检查
check_draw_out_toy([], Player) -> {true, Player};
check_draw_out_toy([Check|L], Player) ->
	case do_check_draw_out_toy(Check, Player) of
		{true, NewPlayer} -> check_draw_out_toy(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

%% 打造加速检查
check_speed_up_forge([], Player) -> {true, Player};
check_speed_up_forge([Check|L], Player) ->
	case do_check_speed_up_forge(Check, Player) of
		{true, NewPlayer} -> check_speed_up_forge(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

%% 穿戴时装检查
check_put_on_fashion([]) -> true;
check_put_on_fashion([Check|L]) ->
	case do_check_put_on_fashion(Check) of
		true -> check_put_on_fashion(L);
		{false, Res} -> {false, Res}
	end.

%% 脱下时装检查
check_put_off_fashion([]) -> true;
check_put_off_fashion([Check|L]) ->
	case do_check_put_off_fashion(Check) of
		true -> check_put_off_fashion(L);
		{false, Res} -> {false, Res}
	end.

%% 激活时装检查
check_active_fashion([]) -> true;
check_active_fashion([Check|L]) ->
	case do_check_active_fashion(Check) of
		true -> check_active_fashion(L);
		{false, Res} -> {false, Res}
	end.

%% 升级时装检查
check_upgrade_fashion([]) -> true;
check_upgrade_fashion([Check|L]) ->
	case do_check_upgrade_fashion(Check) of
		true -> check_upgrade_fashion(L);
		{false, Res} -> {false, Res}
	end.

%% 玩具位开启检查
check_active_toy_slot([], Player) -> {true, Player};
check_active_toy_slot([Check|L], Player) ->
	case do_check_active_toy_slot(Check, Player) of
		{true, NewPlayer} -> check_active_toy_slot(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

%% 玩具位开启检查
check_active_forge_slot([], Player) -> {true, Player};
check_active_forge_slot([Check|L], Player) ->
	case do_check_active_forge_slot(Check, Player) of
		{true, NewPlayer} -> check_active_forge_slot(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

%% 领取玩具套装奖励检查
check_receive_suit_reward([]) -> true;
check_receive_suit_reward([Check|L]) ->
	case do_check_receive_suit_reward(Check) of
		true -> check_receive_suit_reward(L);
		{false, Res} -> {false, Res}
	end.

%% 激活玩具检查
check_active_toy([]) -> true;
check_active_toy([Check|L]) ->
	case do_check_active_toy(Check) of
		true -> check_active_toy(L);
		{false, Res} -> {false, Res}
	end.

%% 升级玩具盒检查
check_upgrade_toy_box([], Player) -> {true, Player};
check_upgrade_toy_box([Check|L], Player) ->
	case do_check_upgrade_toy_box(Check, Player) of
		{true, NewPlayer} -> check_upgrade_toy_box(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

%% 任务阶段奖励检查
check_task_reward([], Player) -> {true, Player};
check_task_reward([Check|L], Player) ->
	case do_check_task_reward(Check, Player) of
		{true, NewPlayer} -> check_task_reward(L, NewPlayer);
		{false, Res, _NewPlayer} -> {false, Res}
	end.

do_check_adopt({has_adopt, ChildSex}) ->
	case ChildSex > 0 of
		true -> {false, ?ERRCODE(err165_child_has_adopt)};
		_ -> true
	end;
do_check_adopt({is_name_exit, Name}) ->
	case lists:member(Name, ?DEFAULT_NAME) of
		true -> true;
		_ ->
			case get_db_child_by_child_name(Name) of
				[_RoleId|_] -> {false, ?ERRCODE(err165_child_name_exits)};
				_ -> true
			end
	end;
do_check_adopt({is_sex_true, Sex}) ->
	case Sex == 1 orelse Sex == 2 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_sex_err)}
	end;
do_check_adopt({is_max_heart_exp, HeartLinkExp}) ->
	case data_child:get_child_max_heart_link_exp() of
		MaxExp when is_integer(MaxExp), HeartLinkExp >= MaxExp ->
			true;
		MaxExp when is_integer(MaxExp) ->
			{false, ?ERRCODE(err165_link_heart_not_finish)};
		_ ->
			{false, ?ERRCODE(err165_link_heart_cfg_err)}
	end;
do_check_adopt({has_receive_all_reward, HeartReward}) ->
	AllReward =
	case HeartReward of
		[{_, _}|_] -> [RewardId||{RewardId, _}<-HeartReward];
		_ -> []
	end,
	CfgAllReward = data_child:get_all_reward(),
	F = fun(TRewardId) ->
		lists:member(TRewardId, AllReward)
		end,
	case lists:all(F, CfgAllReward) of
		true when AllReward =/= [] -> true;
		_ -> {false, ?ERRCODE(err165_not_receive_all_reward)}
	end;
do_check_adopt(_Check) ->
	?ERR("<<Error check_adopt>>"),
	{false, ?FAIL}.

do_check_grow_up({has_adopt, ChildSex}) ->
	case ChildSex > 0 of
		true -> true;
		_ ->
			{false, ?ERRCODE(err165_child_not_adopt)}
	end;
do_check_grow_up({is_open_lv_reach, HeartLinkLv, OpenLv}) ->
	case HeartLinkLv >= OpenLv of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_open_lv_not_reach)}
	end;
do_check_grow_up({is_max_age_year_month, AgeYear, AgeMonth}) ->
	case data_child:get_child_grow_up_cfg(AgeYear, AgeMonth + 1) of
		#child_grow_up_cfg{} -> true;
		_ ->
			case data_child:get_child_grow_up_cfg(AgeYear + 1, AgeMonth + 1) of
				#child_grow_up_cfg{} -> true;
				_ -> {false, ?ERRCODE(err165_child_max_age)}
			end
	end;
do_check_grow_up({is_grow_up_material, GoodId}) ->
	#child_constant_cfg{constant = [{LowFeedId,  _AddExp1}]} = data_child:get_child_kv_cfg(low_feed),
	#child_constant_cfg{constant = [{MidFeedId,  _AddExp2}]} = data_child:get_child_kv_cfg(mid_feed),
	#child_constant_cfg{constant = [{HighFeedId, _AddExp3}]} = data_child:get_child_kv_cfg(high_feed),
	case lists:member(GoodId, [LowFeedId, MidFeedId, HighFeedId]) of
		true -> true;
		_ ->
			{false, ?ERRCODE(err165_not_child_grow_up_material)}
	end;
do_check_grow_up({is_good_enough, GoodId, GoodNum}) ->
	[{_, OwnNum}] = lib_goods_api:get_goods_num(none, [GoodId]),
	case OwnNum > 0 andalso GoodNum > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_good_num_err)}
	end;
do_check_grow_up({has_grow_up_material}) ->
	#child_constant_cfg{constant = [{LowFeedId,  _AddExp1}]} = data_child:get_child_kv_cfg(low_feed),
	#child_constant_cfg{constant = [{MidFeedId,  _AddExp2}]} = data_child:get_child_kv_cfg(mid_feed),
	#child_constant_cfg{constant = [{HighFeedId, _AddExp3}]} = data_child:get_child_kv_cfg(high_feed),
	[{_, OwnNum1}] = lib_goods_api:get_goods_num(none, [LowFeedId]),
	[{_, OwnNum2}] = lib_goods_api:get_goods_num(none, [MidFeedId]),
	[{_, OwnNum3}] = lib_goods_api:get_goods_num(none, [HighFeedId]),
	case OwnNum1 > 0 orelse OwnNum2 > 0 orelse OwnNum3 > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_good_num_err)}
	end;
do_check_grow_up(_Check) ->
	?ERR("<<Error check_grow_up>>"),
	{false, ?FAIL}.


do_check_upgrade_link_heart({is_max_heart_exp, HeartLinkExp}, Player) ->
	case data_child:get_child_max_heart_link_exp() of
		MaxExp when is_integer(MaxExp), HeartLinkExp >= MaxExp ->
			{false, ?ERRCODE(err165_max_link_heart_exp), Player};
		MaxExp when is_integer(MaxExp) ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_link_heart_cfg_err), Player}
	end;
do_check_upgrade_link_heart({is_adopt, ChildSex}, Player) ->
	case ChildSex > 0 of
		true ->
			{false, ?ERRCODE(err165_child_has_adopt), Player};
		_ ->
			{true, Player}
	end;
do_check_upgrade_link_heart({is_upgrade_material, Id}, Player) ->
	#child_constant_cfg{constant = [{GoodId, _AddExp}]} = data_child:get_child_kv_cfg(heart_feed),
	case GoodId == Id of
		true ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_not_upgrade_link_heart_material), Player}
	end;
do_check_upgrade_link_heart({is_material_enough, Id, Num}, Player) ->
	[{_, OwnNum}] = lib_goods_api:get_goods_num(Player, [Id]),
	case OwnNum > 0 andalso Num > 0 of
		true ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_upgrade_link_heart_material_not_enough), Player}
	end;
do_check_upgrade_link_heart({is_money_enough, NeedExp}, Player) ->
	#player_status{bgold = BGold, gold = Gold} = Player,
	case data_child:get_child_kv_cfg(heart_link_exp) of
		#child_constant_cfg{constant = GoodsId} -> ok;
		_ -> GoodsId = 0
	end,
	case data_goods_price:get_goods_price(GoodsId) of
		#goods_price{price_type = PriceType, price = Price} -> ok;
		_ -> PriceType = 0, Price = 0
	end,
	case PriceType > 0 andalso Price > 0 of
		true ->
			case PriceType == 1 orelse PriceType == 2 of
				true -> case (Gold + BGold) >= (Price * NeedExp) of
						 true -> {true, Player};
						 _ ->
							 {false, ?ERRCODE(money_not_enough), Player}
				     end;
				_ ->
					{false, ?ERRCODE(err150_price_err), Player}
			end;
		_ ->
			{false, ?ERRCODE(err150_price_err), Player}
	end;
do_check_upgrade_link_heart({open_day}, Player) ->
	OpenDay = util:get_open_day(),
	CfgDay = case data_child:get_child_kv_cfg(receive_open) of
		         #child_constant_cfg{constant = TCfgDay} -> TCfgDay;
				 _ -> ?QUICK_RECEIVE_DEFAULT_DAY
	         end,
	case OpenDay >= CfgDay of
		true ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_not_receive_open_day), Player}
	end;
do_check_upgrade_link_heart(_Check, Player) ->
	?ERR("<<Error check_upgrade_link_heart>>"),
	{false, ?FAIL, Player}.


do_check_rename({has_adopt, ChildSex}) ->
	case ChildSex > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_adopt)}
	end;
do_check_rename({is_same_name, Name, OldName}) ->
	case Name == OldName of
		false -> true;
		_ -> {false, ?ERRCODE(err165_child_same_name)}
	end;
do_check_rename({is_name_exit, Name}) ->
	case lists:member(Name, ?DEFAULT_NAME) of
		true -> true;
		_ ->
			case get_db_child_by_child_name(Name) of
				[_RoleId|_] -> {false, ?ERRCODE(err165_child_name_exits)};
				_ -> true
			end
	end;
do_check_rename(_Check) ->
	?ERR("<<Error check_rename>>"),
	{false, ?FAIL}.

do_check_show_off({has_adopt, ChildSex}) ->
	case ChildSex > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_adopt)}
	end;
do_check_show_off({is_show_off_times_enough, HasVoteTimes, VoteTimeLimit}) ->
	case HasVoteTimes < VoteTimeLimit of
		true -> true;
		_ -> {false, ?ERRCODE(err165_show_off_times_not_enough)}
	end;
do_check_show_off({is_in_show_off_cd, NowTime, LastShowOffTime}) ->
	case NowTime - LastShowOffTime =< ?SHOW_OFF_CD of
		true -> {false, ?ERRCODE(err165_in_show_off_time_cd)};
		_ -> true
	end;
do_check_show_off(_Check) ->
	?ERR("<<Error check_show_off>>"),
	{false, ?FAIL}.

do_check_active_skill({has_adopt_child, ChildSex}) ->
	case ChildSex > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_adopt)}
	end;
do_check_active_skill({is_child_skill, SkillId}) ->
	SequenceList = data_child:get_child_skill_sequence_list_cfg(),
	F = fun(Seq, TList) ->
		case data_child:get_child_skill_cfg(Seq, 1) of
			#child_skill_cfg{active_skill = [{SkillId, _}]} ->
				[SkillId|TList];
			_ -> TList
		end end,
	SkillList = lists:foldl(F, [], SequenceList),
	case lists:member(SkillId, SkillList) of
		true -> true;
		_ -> {false, ?ERRCODE(err165_is_not_child_skill)}
	end;
do_check_active_skill({is_reach_skill_open_lv, NeedLv, ChildAgeMonth}) ->
	case ChildAgeMonth >= NeedLv of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_reach_skill_open_lv)}
	end;
do_check_active_skill({has_active_skill, SkillId, SkillList}) ->
	case lists:keyfind(SkillId, 1, SkillList) of
		{_, _Lv} -> {false, ?ERRCODE(err165_child_skill_has_active)};
		_ -> true
	end;
do_check_active_skill({has_pre_skill_active, SkillId, SkillList}) ->
	Sequence = lib_child:get_skill_sequence(SkillId),
	#child_skill_cfg{pre_sequence = PreSequence} = data_child:get_child_skill_cfg(Sequence, 1),
	case PreSequence of
		0 -> true;
		_ ->
			case data_child:get_child_skill_cfg(PreSequence, 1) of
				#child_skill_cfg{active_skill = [{PreSkill, _}]} ->
					case SkillList of
						[] -> {false, ?ERRCODE(err165_pre_skill_not_active)};  %% 避免直接激活后面的
						_  ->
							case lists:keyfind(PreSkill, 1, SkillList) of
								{_, _} -> true;
								_ -> {false, ?ERRCODE(err165_pre_skill_not_active)}
							end
					end;
				_ -> {false, ?ERRCODE(err165_skill_err)}
			end
	end;
do_check_active_skill({is_power_reach, SkillId, Power}) ->
	Sequence = lib_child:get_skill_sequence(SkillId),
	#child_skill_cfg{need_power = NeedPower} = data_child:get_child_skill_cfg(Sequence, 1),
	case Power >= NeedPower of
		true -> true;
		_ -> {false, ?ERRCODE(err165_power_not_enough)}
	end;
do_check_active_skill({is_active_material_enough, SkillId}) ->
	Sequence = lib_child:get_skill_sequence(SkillId),
	#child_skill_cfg{active_cost = [{_, GoodId, NeedNum}]} = data_child:get_child_skill_cfg(Sequence, 1),
	[{_, OwnNum}] = lib_goods_api:get_goods_num(none, [GoodId]),
	case OwnNum >= NeedNum of
		true -> true;
		_ -> {false, ?ERRCODE(err165_skill_material_not_enough)}
	end;
do_check_active_skill(_Check) ->
	?ERR("<<Error check_active_skill>>"),
	{false, ?FAIL}.

do_check_upgrade_skill({has_adopt_child, ChildSex}) ->
	case ChildSex > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_adopt)}
	end;
do_check_upgrade_skill({is_child_skill, SkillId}) ->
	SequenceList = data_child:get_child_skill_sequence_list_cfg(),
	F = fun(Seq, TList) ->
		case data_child:get_child_skill_cfg(Seq, 1) of
			#child_skill_cfg{active_skill = [{SkillId, _}]} ->
				[SkillId|TList];
			_ -> TList
		end end,
	SkillList = lists:foldl(F, [], SequenceList),
	case lists:member(SkillId, SkillList) of
		true -> true;
		_ -> {false, ?ERRCODE(err165_is_not_child_skill)}
	end;
do_check_upgrade_skill({has_active_skill, SkillId, SkillList}) ->
	case lists:keyfind(SkillId, 1, SkillList) of
		{_, _Lv} -> true;
		_ -> {false, ?ERRCODE(err165_not_active_child_skill)}
	end;
do_check_upgrade_skill({is_max_skill, SkillInfo}) ->
	{SkillId, Lv} = SkillInfo,
	Sequence = lib_child:get_skill_sequence(SkillId),
	case data_child:get_child_skill_cfg(Sequence, Lv + 1) of
		#child_skill_cfg{} -> true;
		_ -> {false, ?ERRCODE(err165_child_skill_max_lv)}
	end;
do_check_upgrade_skill({is_power_reach, SkillInfo, Power}) ->
	{SkillId, PreLv} = SkillInfo,
	Sequence = lib_child:get_skill_sequence(SkillId),
	#child_skill_cfg{need_power = NeedPower} = data_child:get_child_skill_cfg(Sequence, PreLv + 1),
	case Power >= NeedPower of
		true -> true;
		_ -> {false, ?ERRCODE(err165_power_not_enough)}
	end;
do_check_upgrade_skill({is_upgrade_material_enough, SkillInfo}) ->
	{SkillId, PreLv} = SkillInfo,
	Sequence = lib_child:get_skill_sequence(SkillId),
	#child_skill_cfg{active_cost = [{_, GoodId, NeedNum}]} = data_child:get_child_skill_cfg(Sequence, PreLv + 1),
	[{_, OwnNum}] = lib_goods_api:get_goods_num(none, [GoodId]),
	case OwnNum >= NeedNum of
		true -> true;
		_ -> {false, ?ERRCODE(err165_skill_material_not_enough)}
	end;
do_check_upgrade_skill(_Check) ->
	?ERR("<<Error check_upgrade_skill>>"),
	{false, ?FAIL}.

do_check_active_vehicle({has_adopt_child, ChildSex}) ->
	case ChildSex > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_adopt)}
	end;
do_check_active_vehicle({is_child_vehicle, VehicleId}) ->
	Vehicles = data_child:get_all_child_vehicles(),
	case lists:member(VehicleId, Vehicles) of
		true -> true;
		_ -> {false, ?ERRCODE(err165_not_child_vehicle)}
	end;
do_check_active_vehicle({has_active, VehicleId, VehicleList}) ->
	case lists:keyfind(VehicleId, 1, VehicleList) of
		{_, _} -> {false, ?ERRCODE(err165_has_active_child_vehicle)};
		_ -> true
	end;
do_check_active_vehicle({is_active_material_enough, VehicleId}) ->
	case data_child:get_child_vehicle_cfg(VehicleId, 1) of
		#child_vehicle_cfg{upgrade_cost = [{_, GoodId, NeedNum}]} ->
			[{_, OwnNum}] = lib_goods_api:get_goods_num(none, [GoodId]),
			case OwnNum >= NeedNum of
				true -> true;
				_ -> {false, ?ERRCODE(err165_vehicle_material_not_enough)}
			end;
		_ -> {false, ?ERRCODE(err165_not_child_vehicle)}
	end;
do_check_active_vehicle(_Check) ->
	?ERR("<<Error check_active_vehicle>>"),
	{false, ?FAIL}.

do_check_upgrade_child_vehicle({has_adopt_child, ChildSex}) ->
	case ChildSex > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_adopt)}
	end;
do_check_upgrade_child_vehicle({is_child_vehicle, VehicleId}) ->
	Vehicles = data_child:get_all_child_vehicles(),
	case lists:member(VehicleId, Vehicles) of
		true -> true;
		_ -> {false, ?ERRCODE(err165_not_child_vehicle)}
	end;
do_check_upgrade_child_vehicle({has_active, VehicleId, VehicleList}) ->
	case lists:keyfind(VehicleId, 1, VehicleList) of
		{_, _} -> true;
		_ -> {false, ?ERRCODE(err165_has_active_child_vehicle)}
	end;
do_check_upgrade_child_vehicle({is_max_stage, VehicleInfo}) ->
	{VehicleId, Stage} = VehicleInfo,
	case data_child:get_child_vehicle_cfg(VehicleId, Stage + 1) of
		#child_vehicle_cfg{} -> true;
		_ -> {false, ?ERRCODE(err165_child_vehicle_max_stage)}
	end;
do_check_upgrade_child_vehicle({is_upgrade_material_enough, VehicleInfo}) ->
	{VehicleId, Stage} = VehicleInfo,
	case data_child:get_child_vehicle_cfg(VehicleId, Stage + 1) of
		#child_vehicle_cfg{upgrade_cost = [{_, GoodId, NeedNum}]} ->
			[{_, OwnNum}] = lib_goods_api:get_goods_num(none, [GoodId]),
			case OwnNum >= NeedNum of
				true -> true;
				_ -> {false, ?ERRCODE(err165_vehicle_material_not_enough)}
			end;
		_ -> {false, ?ERRCODE(err165_child_vehicle_max_stage)}
	end;
do_check_upgrade_child_vehicle(_Check) ->
	?ERR("<<Error check_upgrade_child_vehicle>>"),
	{false, ?FAIL}.

do_check_stren_toy({has_adopt_child, ChildSex}, Player) ->
	case ChildSex > 0 of
		true ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_child_not_adopt), Player}
	end;
do_check_stren_toy({is_toy, GoodId}, Player) ->
	case lib_goods_api:get_goods_info(GoodId, ?GOODS_LOC_CHILD_TOY_BAG) of
		#goods{} = GoodInfo -> ok;
		_ ->
			case lib_goods_api:get_goods_info(GoodId, ?GOODS_LOC_CHILD_TOY_SLOT) of
				#goods{} = GoodInfo -> ok;
				_ -> GoodInfo = []
			end
	end,
	case GoodInfo of
		#goods{type = ?GOODS_TYPE_BABY} ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_has_not_toy), Player}
	end;
do_check_stren_toy({aim_lv_legal, GoodId, AimLv}, Player) ->
	case lib_goods_api:get_goods_info(GoodId, ?GOODS_LOC_CHILD_TOY_BAG) of
		#goods{} = GoodInfo -> ok;
		_ ->
			case lib_goods_api:get_goods_info(GoodId, ?GOODS_LOC_CHILD_TOY_SLOT) of
				#goods{} = GoodInfo -> ok;
				_ -> GoodInfo = []
			end
	end,
	case GoodInfo of
		#goods{goods_id = GoodTypeId, extra_data = [{?GOODS_OTHER_KEY_CHILD_TOY_LV, Lv}]} ->
			ensure_aim_lv_legal(Player, GoodTypeId, Lv, AimLv);
		#goods{goods_id = GoodTypeId} ->
			ensure_aim_lv_legal(Player, GoodTypeId, 0, AimLv);
		_ ->
			{false, ?ERRCODE(err165_has_not_toy), Player}
	end;
do_check_stren_toy({cost_enough, GoodId, AimLv}, Player) ->
	case lib_goods_api:get_goods_info(GoodId, ?GOODS_LOC_CHILD_TOY_BAG) of
		#goods{} = GoodInfo -> ok;
		_ ->
			case lib_goods_api:get_goods_info(GoodId, ?GOODS_LOC_CHILD_TOY_SLOT) of
				#goods{} = GoodInfo -> ok;
				_ -> GoodInfo = []
			end
	end,
	case GoodInfo of
		#goods{type = ?GOODS_TYPE_BABY, goods_id = GoodTypeId, extra_data = ExtraData} ->
			case ExtraData of
				[{?GOODS_OTHER_KEY_CHILD_TOY_LV, Lv}] -> ok;
				_ -> Lv = 0
			end,
			#child_toy_cfg{toy_type = Type, toy_color = Color} = data_child:get_child_toy_cfg(GoodTypeId),
			CanLv = lib_child_items:calc_can_stren_lv(Player, Type, Color, Lv, [], true),
			case CanLv == Lv of
				true -> {false, ?ERRCODE(goods_not_enough), Player};
				_ ->
					NewLv = ?IF(CanLv >= AimLv, AimLv, CanLv),
					CostList = lib_child_items:calc_cost(Type, Color, Lv, NewLv, []),
					case lib_goods_api:check_object_list(Player, CostList) of
						true -> {true, Player};
						{false, Res} -> {false, Res, Player};
						_ -> {false, ?ERRCODE(goods_not_enough), Player}
					end
			end;
		_ ->
			{false, ?ERRCODE(err165_has_not_toy), Player}
	end;
do_check_stren_toy(_Check, Player) ->
	?ERR("<<Error check_stren_toy>>"),
	{false, ?FAIL, Player}.

ensure_aim_lv_legal(Player, GoodTypeId, Lv, AimLv) ->
	case data_child:get_child_toy_cfg(GoodTypeId) of
		#child_toy_cfg{toy_color = Color, toy_type = Type} ->
			case data_child:get_toy_stren_cfg(Type, Color, Lv + 1) of
				#child_toy_stren_cfg{} ->
					case data_child:get_toy_stren_cfg(Type, Color, AimLv) of
						#child_toy_stren_cfg{} ->
							case AimLv > Lv of
								true ->
									{true, Player};
								_ ->
									{false, ?ERRCODE(err165_toy_aim_lv_err), Player}
							end;
						_ ->
							{false, ?ERRCODE(err165_toy_aim_lv_max), Player}
					end;
				_ ->
					{false, ?ERRCODE(err165_toy_max_lv), Player}
			end;
		_ ->
			?ERR("<<Error child toy config!>>"),
			{false, ?ERRCODE(err165_has_not_toy), Player}
	end.

do_check_inlay_toy({has_adopt_child, ChildSex}, Player) ->
	case ChildSex > 0 of
		true ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_child_not_adopt), Player}
	end;
do_check_inlay_toy({is_toy, GoodId}, Player) ->
	case lib_goods_api:get_goods_info(GoodId, ?GOODS_LOC_CHILD_TOY_BAG) of
		#goods{type = ?GOODS_TYPE_BABY} ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_has_not_toy), Player}
	end;
do_check_inlay_toy({is_slot_open, ToyList, SlotId}, Player) ->
	case lists:keyfind(SlotId, 1, ToyList) of
		{_, _} ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_toy_slot_not_open), Player}
	end;
do_check_inlay_toy({can_carry, ToyList, CanCarry, SlotId, GoodId}, Player) ->
	#player_status{status_child = StatusChild} = Player,
	#status_child{toy_list = ToyList} = StatusChild,
	case lists:keyfind(SlotId, 1, ToyList) of
		{_, _} ->
			NewToyList = lists:keystore(SlotId, 1, ToyList, {SlotId, GoodId}),
			case lib_child_items:calc_toy_weight(NewToyList) > CanCarry of
				true ->
					{false, ?ERRCODE(err165_can_not_carry_toy), Player};
				_ ->
					{true, Player}
			end;
		_ ->
			{false, ?ERRCODE(err165_toy_slot_not_open), Player}
	end;
do_check_inlay_toy(_Check, Player) ->
	?ERR("<<Error check_inlay_toy>>"),
	{false, ?FAIL, Player}.

do_check_load_off_toy({is_slot_open, ToyList, SlotId}, Player) ->
	case lists:keyfind(SlotId, 1, ToyList) of
		{_, _} ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_toy_slot_not_open), Player}
	end;
do_check_load_off_toy({has_good, SlotId, ToyList}, Player) ->
	case lists:keyfind(SlotId, 1, ToyList) of
		{_, GoodId} when GoodId > 0  ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_slot_not_good), Player}
	end;
do_check_load_off_toy(_Check, Player) ->
	?ERR("<<Error check_load_off_toy>>"),
	{false, ?FAIL, Player}.

do_check_compose_toy({has_adopt_child, ChildSex}, Player) ->
	case ChildSex > 0 of
		true ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_child_not_adopt), Player}
	end;
do_check_compose_toy({goods_enough_six, GoodsList}, Player) ->
	case is_list(GoodsList) andalso length(GoodsList) == ?TOY_FORGE_MATERIAL_NUM of
		true ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_forge_material_not_enough), Player}
	end;
do_check_compose_toy({is_same_color, GoodsList}, Player) ->
	F = fun(GoodId, TList) ->
		case lib_goods_api:get_goods_info(GoodId, ?GOODS_LOC_CHILD_TOY_BAG) of
			#goods{goods_id = GoodTypeId, type = ?GOODS_TYPE_BABY} ->
				case data_child:get_child_toy_cfg(GoodTypeId) of
					#child_toy_cfg{toy_color = TColor} ->
						case lists:keyfind(TColor, 1, TList) of
							{_, TNum} -> lists:keystore(TColor, 1, TList, {TColor, TNum+1});
							_         -> lists:keystore(TColor, 1, TList, {TColor, 1})
						end;
					_ -> TList
				end;
			_ -> TList
		end
	end,
	case lists:foldl(F, [], GoodsList) of
		[{_Color, Num}|_] ->
			case Num == length(GoodsList) of
				true ->
					{true, Player};
				_ ->
					{false, ?ERRCODE(err165_not_same_color), Player}
			end;
		_ ->
			{false, ?ERRCODE(err165_not_same_color), Player}
	end;
do_check_compose_toy({has_inlay, ToyList, GoodsList}, Player) ->
	F = fun(GoodId) ->
		case lists:keyfind(GoodId, 2, ToyList) of
			{_, _} -> true;
			_      -> false
		end
	end,
	case lists:any(F, GoodsList) of
		true ->
			{false, ?ERRCODE(err165_toy_has_inlay), Player};
		_ ->
			{true, Player}
	end;
do_check_compose_toy({max_color, GoodsList}, Player) ->
	[GoodId|_] = GoodsList,
	case lib_goods_api:get_goods_info(GoodId, ?GOODS_LOC_CHILD_TOY_BAG) of
		#goods{goods_id = GoodTypeId} ->
			case data_child:get_child_toy_cfg(GoodTypeId) of
				#child_toy_cfg{toy_type = Type, toy_color = Color} ->
					case data_child:get_child_toy_cfg2(Type, Color) of
						[_TGoodTypeId|_] ->
							{true, Player};
						_ ->
							{false, ?ERRCODE(err165_toy_config_err), Player}
					end;
				_ ->
					?ERR("<<Error err165_toy_config_err>>"),
					{false, ?ERRCODE(err165_toy_config_err), Player}
			end;
		_ ->
			?ERR("<<Error err165_toy_config_err>>"),
			{false, ?ERRCODE(err165_has_not_toy), Player}
	end;
do_check_compose_toy(_Check, Player) ->
	?ERR("<<Error check_forge_toy>>"),
	{false, ?FAIL, Player}.

do_check_decompose_toy({is_on_slot, ToyList, GoodId}, Player) ->
	case lists:keyfind(GoodId, 2, ToyList) of
		{_, _} ->
			{false, ?ERRCODE(err165_toy_is_on_slot), Player};
		_ ->
			{true, Player}
	end;
do_check_decompose_toy({has_stren, GoodId}, Player) ->
	case lib_goods_api:get_goods_info(GoodId, ?GOODS_LOC_CHILD_TOY_BAG) of
		#goods{} ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_has_not_toy), Player}
	end;
do_check_decompose_toy(_Check, Player) ->
	?ERR("<<Error check_decompose_toy>>"),
	{false, ?FAIL, Player}.

do_check_forge_toy({has_adopt_child, ChildSex}, Player) ->
	case ChildSex > 0 of
		true ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_child_not_adopt), Player}
	end;
do_check_forge_toy({has_open, ForgeList, SlotId}, Player) ->
	case lists:keyfind(SlotId, #forge_slot.slot_id, ForgeList) of
		#forge_slot{} ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_forge_slot_not_open), Player}
	end;
do_check_forge_toy({is_using, ForgeList, SlotId}, Player) ->
	case lists:keyfind(SlotId, #forge_slot.slot_id, ForgeList) of
		#forge_slot{status = Status} when Status > ?FORGE_TOY_WAIT ->
			{false, ?ERRCODE(err165_forge_slot_is_using), Player};
		_ ->
			{true, Player}
	end;
do_check_forge_toy(_Check, Player) ->
	?ERR("<<Error check_forge_toy>>"),
	{false, ?FAIL, Player}.

do_check_draw_out_toy({has_open, ForgeList, SlotId}, Player) ->
	case lists:keyfind(SlotId, #forge_slot.slot_id, ForgeList) of
		#forge_slot{} ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_forge_slot_not_open), Player}
	end;
do_check_draw_out_toy({is_finish, ForgeList, SlotId}, Player) ->
	case lists:keyfind(SlotId, #forge_slot.slot_id, ForgeList) of
		#forge_slot{start_time = StartTime, select_id = SelectId, status = Status} ->
			case data_child:get_toy_forge_time_cfg(SelectId) of
				#toy_forge_time_cfg{need_time = NeedTime} ->
					NowTime = utime:unixtime(),
					case Status > ?FORGE_TOY_USING of
						true ->
							{true, Player};
						_ ->
							case NowTime >= StartTime + NeedTime of
								true ->
									{true, Player};
								_ ->
									{false, ?ERRCODE(err165_forge_has_not_finish), Player}
							end
					end;
				_ ->
					{false, ?ERRCODE(err165_forge_has_not_start), Player}
			end;
		_ ->
			{false, ?ERRCODE(err165_forge_slot_not_open), Player}
	end;
do_check_draw_out_toy(_Check, Player) ->
	?ERR("<<Error check_forge_toy>>"),
	{false, ?FAIL, Player}.

do_check_speed_up_forge({has_open, ForgeList, SlotId}, Player) ->
	case lists:keyfind(SlotId, #forge_slot.slot_id, ForgeList) of
		#forge_slot{} ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_forge_slot_not_open), Player}
	end;
do_check_speed_up_forge({use_status, ForgeList, SlotId, NowTime}, Player) ->
	case lists:keyfind(SlotId, #forge_slot.slot_id, ForgeList) of
		#forge_slot{start_time = StartTime, select_id = SelectId, status = Status} ->
			case Status > ?FORGE_TOY_USING of
				true -> {false, ?ERRCODE(err165_forge_has_finish), Player};
				_ ->
					case data_child:get_toy_forge_time_cfg(SelectId) of
						#toy_forge_time_cfg{need_time = NeedTime} ->
							case NowTime < (StartTime + NeedTime) of
								true -> {true, Player};
								_    -> {false, ?ERRCODE(err165_forge_has_finish), Player}
							end;
						_ ->
							{false, ?ERRCODE(err165_forge_has_not_start), Player}
					end
			end;
		_ ->
			{false, ?ERRCODE(err165_forge_slot_not_open), Player}
	end;
do_check_speed_up_forge({cost_enough, ForgeList, SlotId, NowTime}, Player) ->
	case lists:keyfind(SlotId, #forge_slot.slot_id, ForgeList) of
		#forge_slot{start_time = StartTime, select_id = SelectId} ->
			case data_child:get_toy_forge_time_cfg(SelectId) of
				#toy_forge_time_cfg{need_time = NeedTime} -> skip;
				_ -> NeedTime = 0
			end,
			LeftTime = StartTime + NeedTime - NowTime,
			case LeftTime =< 0 of
				true -> {false, ?ERRCODE(err165_forge_has_finish), Player};
				_    ->
					case data_child:get_toy_speed_up_cfg(LeftTime) of
						[{_, _NeedMoney}] = Cost ->
							case ensure_money(Player, Cost) of
								true -> {true, Player};
								_    -> {false, ?ERRCODE(err165_money_not_enough), Player}
							end;
						_ ->
							case LeftTime =< ?TOY_SPEED_UP_TIME_RANGE of
								true -> {true, Player};
								_ ->
									?ERR("<<Error toy_speed_up_cfg>>"),
									{false, ?ERRCODE(err165_toy_speed_up_cfg), Player}
							end
					end
			end;
		_ ->
			{false, ?ERRCODE(err165_forge_slot_not_open), Player}
	end;
do_check_speed_up_forge(_Check, Player) ->
	?ERR("<<Error check_speed_up_forge>>"),
	{false, ?FAIL, Player}.

do_check_put_on_fashion({has_adopt_child, ChildSex}) ->
	case ChildSex > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_adopt)}
	end;
do_check_put_on_fashion({has_fashion, FashionList, FashionId}) ->
	case lists:keyfind(FashionId, 1, FashionList) of
		{_, _} -> true;
		_      -> {false, ?ERRCODE(err165_has_not_fashion)}
	end;
do_check_put_on_fashion({has_dressed, DressUps, FashionId}) ->
	case lists:keyfind(FashionId, 2, DressUps) of
		{_, _} -> {false, ?ERRCODE(err165_has_dress_up)};
		_      -> true
	end;
do_check_put_on_fashion({is_type_true, FashionId, Type}) ->
	case data_child:get_child_fashion_cfg(FashionId, 1) of
		#child_fashion_cfg{fashion_type = FType} ->
			case FType == Type of
				true -> true;
				_ -> {false, ?ERRCODE(err165_dress_type_err)}
			end;
		_ -> {false, ?ERRCODE(err165_not_fashion)}
	end;
do_check_put_on_fashion(_Check) ->
	?ERR("<<Error check_put_on_fashion>>"),
	{false, ?FAIL}.

do_check_put_off_fashion({has_adopt_child, ChildSex}) ->
	case ChildSex > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_adopt)}
	end;
do_check_put_off_fashion({has_fashion, FashionList, FashionId}) ->
	case lists:keyfind(FashionId, 1, FashionList) of
		{_, _} -> true;
		_      -> {false, ?ERRCODE(err165_has_not_fashion)}
	end;
do_check_put_off_fashion({has_dressed, DressUps, FashionId}) ->
	case lists:keyfind(FashionId, 2, DressUps) of
		{_, _} -> true;
		_      -> {false, ?ERRCODE(err165_has_not_dress_up)}
	end;
do_check_put_off_fashion({is_type_true, FashionId, Type}) ->
	case data_child:get_child_fashion_cfg(FashionId, 1) of
		#child_fashion_cfg{fashion_type = FType} ->
			case FType == Type of
				true -> true;
				_ -> {false, ?ERRCODE(err165_dress_type_err)}
			end;
		_ -> {false, ?ERRCODE(err165_not_fashion)}
	end;
do_check_put_off_fashion(_Check) ->
	?ERR("<<Error check_put_off_fashion>>"),
	{false, ?FAIL}.

do_check_active_fashion({has_adopt_child, ChildSex}) ->
	case ChildSex > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_adopt)}
	end;
do_check_active_fashion({is_reach_fashion_open_lv, NeedLv, ChildAgeYear}) ->
	case ChildAgeYear >= NeedLv of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_reach_fashion_open_lv)}
	end;
do_check_active_fashion({has_active, FashionList, FashionId}) ->
	case lists:keyfind(FashionId, 1, FashionList) of
		{_, _} -> {false, ?ERRCODE(err165_fashion_has_active)};
		_      -> true
	end;
do_check_active_fashion(_Check) ->
	?ERR("<<Error check_active_fashion>>"),
	{false, ?FAIL}.

do_check_upgrade_fashion({max_lv, FashionList, FashionId}) ->
	case lists:keyfind(FashionId, 1, FashionList) of
		{_, Lv} ->
			case data_child:get_child_fashion_cfg(FashionId, Lv + 1) of
				#child_fashion_cfg{} -> true;
				_ -> {false, ?ERRCODE(err165_fashion_max_lv)}
			end;
		_ -> {false, ?ERRCODE(err165_has_not_fashion)}
	end;
do_check_upgrade_fashion(_Check) ->
	?ERR("<<Error check_upgrade_fashion>>"),
	{false, ?FAIL}.

do_check_active_toy_slot({has_adopt_child, ChildSex}, Player) ->
	case ChildSex > 0 of
		true ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_child_not_adopt), Player}
	end;
do_check_active_toy_slot({has_active, ToyList, SlotId}, Player) ->
	case lists:keyfind(SlotId, 1, ToyList) of
		{_, _} -> {false, ?ERRCODE(err165_slot_has_open), Player};
		_      -> {true, Player}
	end;
do_check_active_toy_slot({cost_enough, SlotId}, Player) ->
	case data_child:get_toy_slot_open_cfg(SlotId) of
		[{Type, Money}|_] when is_integer(Type) ->
			case goods_del:is_enough_money(Player, Money, Type) of
				true -> {true, Player};
				_ -> {false, ?ERRCODE(err151_not_enough_gold), Player}
			end;
		_ ->  {false, ?ERRCODE(err165_slot_auto_open), Player}
	end;
do_check_active_toy_slot({is_toy_slot, SlotId}, Player) ->
	case lists:member(SlotId, ?TOY_SLOTS) of
		true -> {true, Player};
		_    -> {false, ?ERRCODE(err165_not_slot), Player}
	end;
do_check_active_toy_slot(_Check, Player) ->
	?ERR("<<Error check_active_toy_slot>>"),
	{false, ?FAIL, Player}.

do_check_active_forge_slot({has_adopt_child, ChildSex}, Player) ->
	case ChildSex > 0 of
		true ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_child_not_adopt), Player}
	end;
do_check_active_forge_slot({has_active, ForgeList, SlotId}, Player) ->
	case lists:keyfind(SlotId, #forge_slot.slot_id, ForgeList) of
		#forge_slot{} -> {false, ?ERRCODE(err165_slot_has_open), Player};
		_      -> {true, Player}
	end;
do_check_active_forge_slot({cost_enough, SlotId}, Player) ->
	case data_child:get_toy_forge_slot_cfg(SlotId) of
		[{Type, Money}|_] when is_integer(Type) ->
			case goods_del:is_enough_money(Player, Money, Type) of
				true -> {true, Player};
				_ -> {false, ?ERRCODE(err151_not_enough_gold), Player}
			end;
		_ ->  {false, ?ERRCODE(err165_slot_auto_open), Player}
	end;
do_check_active_forge_slot({is_forge_slot, SlotId}, Player) ->
	case lists:member(SlotId, ?FORGE_SLOTS) of
		true -> {true, Player};
		_    -> {false, ?ERRCODE(err165_not_slot), Player}
	end;
do_check_active_forge_slot(_Check, Player) ->
	?ERR("<<Error check_active_forge_slot>>"),
	{false, ?FAIL, Player}.

do_check_receive_suit_reward({has_adopt_child, ChildSex}) ->
	case ChildSex > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_adopt)}
	end;
do_check_receive_suit_reward({is_suit_type_true, SuitType}) ->
	SuitTypeList = data_child:get_all_toy_suit_cfg(),
	case lists:member(SuitType, SuitTypeList) of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_suit_type)}
	end;
do_check_receive_suit_reward({has_receive, ToySuits, SuitType}) ->
	case maps:get(SuitType, ToySuits, []) of
		[] -> {false, ?ERRCODE(err165_child_not_active_toy)};
		#toy_suit{status = Status} ->
			case Status of
				?TOY_SUIT_NOT_COLLECT_ALL ->
					{false, ?ERRCODE(err165_child_progress_not_reach)};
				?TOY_SUIT_COLLECT_ALL ->
					true;
				_ ->
					{false, ?ERRCODE(err165_child_suit_has_receive)}
			end
	end;
do_check_receive_suit_reward(_Check) ->
	?ERR("<<Error check_receive_suit_reward>>"),
	{false, ?FAIL}.

do_check_active_toy({has_adopt_child, ChildSex}) ->
	case ChildSex > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_child_not_adopt)}
	end;
do_check_active_toy({has_active, ToySuits, SuitType, ToyId}) ->
	case maps:get(SuitType, ToySuits, []) of
		[] -> true;
		#toy_suit{toy_list = ToyList} ->
			case lists:member(ToyId, ToyList) of
				true -> {false, ?ERRCODE(err165_child_toy_has_active)};
				_ -> true
			end
	end;
do_check_active_toy({is_toy_material_enough, ToyId}) ->
	[{_, OwnNum}] = lib_goods_api:get_goods_num(none, [ToyId]),
	case OwnNum > 0 of
		true -> true;
		_ -> {false, ?ERRCODE(err165_toy_material_not_enough)}
	end;
do_check_active_toy({is_suit_type_true, SuitType, ToyId}) ->
	case data_child:get_child_toy_new_cfg(ToyId) of
		#child_toy_new_cfg{suit_type = TSuitType} when SuitType == TSuitType ->
			true;
		#child_toy_new_cfg{} ->
			{false, ?ERRCODE(err165_toy_suit_type_err)};
		_ ->
			{false, ?ERRCODE(err165_toy_cfg_err)}
	end;
do_check_active_toy(_Check) ->
	?ERR("<<Error check_active_toy>>"),
	{false, ?FAIL}.

do_check_upgrade_toy_box({has_adopt_child, ChildSex}, Player) ->
	case ChildSex > 0 of
		true ->
			{true, Player};
		_ ->
			{false, ?ERRCODE(err165_child_not_adopt), Player}
	end;
do_check_upgrade_toy_box({is_upgrade_material_enough, BoxLv}, Player) ->
	case data_child:get_child_toy_box_upgrade_cfg(BoxLv + 1) of
		#child_toy_box_upgrade_cfg{} ->
			case data_child:get_child_toy_box_upgrade_cfg(BoxLv) of
				#child_toy_box_upgrade_cfg{next_cost = [{_, GoodTypeId, Num}]} ->
					OwnNum = lib_goods_api:get_currency(Player, GoodTypeId),
					case OwnNum >= Num of
						true ->
							{true, Player};
						_ ->
							{false, ?ERRCODE(err165_toy_material_not_enough), Player}
					end;
				_ ->
					{false, ?ERRCODE(err165_toy_box_upgrade_cfg_err), Player}
			end;
		_ ->
			{false, ?ERRCODE(err165_toy_box_max_lv), Player}
	end;
do_check_upgrade_toy_box(_Check, Player) ->
	?ERR("<<Error check_upgrade_toy_box>>"),
	{false, ?FAIL, Player}.

do_check_task_reward({has_receive_reward, RewardId, HeartLinkReward}, Player) ->
	case lists:keyfind(RewardId, 1, HeartLinkReward) of
		{_, _} ->
			{false, ?ERRCODE(err165_child_heart_link_reward_received), Player};
		_ ->
			{true, Player}
	end;
do_check_task_reward({has_receive_pre, RewardId, HeartLinkReward}, Player) ->
	case RewardId == 1 of
		true ->
			{true, Player};
		_ ->
			PreRewardId = max(1, RewardId - 1),
			case lists:keyfind(PreRewardId, 1, HeartLinkReward) of
				{_, _} ->
					{true, Player};
				_ ->
					{false, ?ERRCODE(err165_child_reward_not_receive_pre), Player}
			end
	end;
do_check_task_reward(_Check, Player) ->
	?ERR("<<Error do_check_task_reward>>"),
	{false, ?FAIL, Player}.

%% ----------------------------------------------------------------------
ensure_money(Player, Cost) ->
	#player_status{gold = Gold, bgold = BGold, coin = Coin} = Player,
	case Cost of
		[{?TYPE_GOLD, NMoney}] ->
			?IF(Gold >= NMoney, true, false);
		[{?TYPE_BGOLD, NMoney}] ->
			?IF(BGold >= NMoney, true, false);
		[{?TYPE_COIN, NMoney}] ->
			?IF(Coin >= NMoney, true, false);
		_ ->
			false
	end.

%% ----------------------------------------------------------------------
%% @doc 数据相关
%% ----------------------------------------------------------------------
%% ------------ 处理内存数据 ------------
%% 基础培养相关
save_dict_status_child(StatusChild, Player) ->
	Player#player_status{status_child = StatusChild}.

%% 日常任务相关
update_dict_child_daily_tasks(DailyTaskList, Player) ->
	#player_status{status_child = StatusChild} = Player,
	NewStatusChild = StatusChild#status_child{daily_task = DailyTaskList},
	Player#player_status{status_child = NewStatusChild}.

%% 点赞相关
save_dict_vote_log(BeVoteLog, Player) ->
	#player_status{status_child = StatusChild} = Player,
	NewStatusChild = StatusChild#status_child{be_voted_log = BeVoteLog},
	Player#player_status{status_child = NewStatusChild}.

%% ------------ 处理数据库数据 ------------ %% TODO:ChildName
%% 基础培养相关
save_db_child(RoleId, ChildName, ChildSex, ChildAgeYear, ChildAgeMonth, ChildAgeExp, HeartLinkExp, HeartLinkReward, VoteTimes, ShowOffTimes, LastShowOffTime, IsFollow, ShowVehicle, BoxLv, AdoptTime) ->
	Sql = io_lib:format(?SQL_INSERT_CHILD, [RoleId, ChildName, ChildSex, ChildAgeYear, ChildAgeMonth,
		ChildAgeExp, HeartLinkExp, util:term_to_string(HeartLinkReward), VoteTimes, ShowOffTimes, utime:unixtime(),
		LastShowOffTime, IsFollow, ShowVehicle, BoxLv, AdoptTime]),
	db:execute(Sql).

get_db_child_info(RoleId) ->
	db:get_row(io_lib:format(?SQL_SELECT_CHILD, [RoleId])).

get_db_child_by_child_name(ChildName) ->
	db:get_row(io_lib:format(?SQL_SELECT_CHILD_NAME, [ChildName])).

update_db_child_name(RoleId, ChildName) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_NAME, [ChildName, RoleId])).

update_db_child_age(RoleId, AgeYear1, AgeMonth1, AgeExp1) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_AGE, [AgeYear1, AgeMonth1, AgeExp1, RoleId])).

update_db_child_link_heart(RoleId, LinkHeartExp) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_LINK_HEART, [LinkHeartExp, RoleId])).

update_db_child_link_heart_reward(RoleId, RewardList) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_LINK_EXP_REWARD, [util:term_to_string(RewardList), RoleId])).

update_db_child_vote_times(RoleId, VoteTimes, RefreshTime) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_VOTE_TIMES, [VoteTimes, RefreshTime, RoleId])).

update_db_child_show_off_times(RoleId, ShowOffTimes, RefreshTime) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_SHOW_OFF_TIMES, [ShowOffTimes, RefreshTime, RoleId])).

update_db_vote_count(RoleId, NewVoteTimes, NewShowOffTimes) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_VOTE_COUNT, [NewVoteTimes, NewShowOffTimes, utime:unixtime(), RoleId])).

update_db_roles_vote_count(NewVoteTimes, NewShowOffTimes) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_ROLES_VOTE_COUNT, [NewVoteTimes, NewShowOffTimes])).

update_db_child_follow_status(RoleId, FollowStatus) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_FOLLOW_STATUS, [FollowStatus, RoleId])).

update_db_vehicle_follow_status(RoleId, ShowVehicle) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_SHOW_VEHICLE, [ShowVehicle, RoleId])).

%% 日常任务相关
save_db_child_daily_task(RoleId, DailyTask) ->
	#child_daily_task{
		sequence   = Sequence,
		detail_id  = DetailIdList,
		progress   = Progress,
		task_state = TaskState} = DailyTask,
	db:execute(io_lib:format(?SQL_INSERT_CHILD_DAILY_TASK, [RoleId, Sequence, util:term_to_string(DetailIdList), Progress, TaskState])).

get_db_child_daily_task(RoleId) ->
	db:get_all(io_lib:format(?SQL_SELECT_CHILD_DAILY_TASK, [RoleId])).

update_db_child_daily_task(RoleId, DailyTask) ->
	#child_daily_task{
		sequence   = Sequence,
		progress   = Progress,
		detail_id  = DetailIdList,
		task_state = TaskState} = DailyTask,
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_DAILY_TASK, [util:term_to_string(DetailIdList), Progress, TaskState, RoleId, Sequence])).

%% 点赞相关
save_db_child_vote_log(BeVoteRoleId, VoteId, VoteName, VoteTime, FeedBackStatus) ->
	db:execute(io_lib:format(?SQL_INSERT_CHILD_BE_VOTED_LOG, [BeVoteRoleId, VoteId, VoteName, VoteTime, FeedBackStatus])).

get_db_child_vote_log(RoleId) ->
	db:get_all(io_lib:format(?SQL_SELECT_CHILD_BE_VOTED_LOG, [RoleId])).

get_vote_role_list(RoleId) ->
	db:get_all(io_lib:format(?SQL_SELECT_CHILD_VOTE_ID_LIST, [RoleId])).

update_db_child_vote_back_status(BeVoteRoleId, VoteRoleId, FeedBackStatus) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_VOTE_FEED_BACK_STATUS, [FeedBackStatus, BeVoteRoleId, VoteRoleId])).

update_db_child_last_show_off_time(RoleId, ShowOffTime) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_LAST_SHOW_OFF_TIME, [ShowOffTime, RoleId])).

delete_db_child_vote_log() ->
	db:execute(io_lib:format(?SQL_DELETE_CHILD_VOTE_LOG, [])).

%% 排行榜相关
save_db_child_vote_rank(RoleId, ChildName, BeVoteCount) ->
	db:execute(io_lib:format(?SQL_INSERT_CHILD_VOTE_RANK, [RoleId, ChildName, BeVoteCount])).

get_db_child_vote_rank() ->
	db:get_all(io_lib:format(?SQL_SELECT_CHILD_VOTE_RANK, [])).

update_db_child_vote_rank_child_name(RoleId, ChildName) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_VOTE_RANK_CHILD_NAME, [ChildName, RoleId])).

update_db_be_voted_count(RoleId, BeVotedCount) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_BE_VOTED_COUNT, [BeVotedCount, RoleId])).

delete_db_child_vote_rank() ->
	db:execute(io_lib:format(?SQL_DELETE_CHILD_VOTE_RANK, [])).

%% 技能相关
save_db_child_skill(RoleId, SkillId, SkillLv) ->
	db:execute(io_lib:format(?SQL_SAVE_CHILD_SKILL, [RoleId, SkillId, SkillLv])).

get_db_child_skill(RoleId) ->
	db:get_all(io_lib:format(?SQL_SELECT_CHILD_SKILL, [RoleId])).

update_db_child_skill(RoleId, SkillId, SkillLv) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_SKILL, [SkillLv, RoleId, SkillId])).

%% 载具相关
save_db_child_vehicle(RoleId, VehicleId, Stage) ->
	db:execute(io_lib:format(?SQL_SAVE_CHILD_VEHICLE, [RoleId, VehicleId, Stage])).

get_db_child_vehicle(RoleId) ->
	db:get_all(io_lib:format(?SQL_SELECT_CHILD_VEHICLE, [RoleId])).

update_db_child_vehicle(RoleId, VehicleId, Stage) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_VEHICLE, [Stage, RoleId, VehicleId])).

%% 玩具相关
save_db_toy_slot_info(RoleId, SlotId, GoodId) ->
	db:execute(io_lib:format(?SQL_SAVE_CHILD_TOY_SLOT, [RoleId, SlotId, GoodId])).

get_db_toy_slot_info(RoleId) ->
	db:get_all(io_lib:format(?SQL_SELECT_CHILD_TOY_SLOT, [RoleId])).

update_db_toy_slot_info(RoleId, SlotId, GoodId) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_TOY_SLOT, [GoodId, RoleId, SlotId])).

%%db_update_carry_weight(RoleId, ToyWeight) ->
%%	Sql = io_lib:format(?SQL_UPDATE_CHILD_TOY_SLOT, [GoodId, RoleId, SlotId]),
%%	db:execute(Sql).

save_db_forge_slot_info(RoleId, SlotId, StartTime, Status, SelectId) ->
	db:execute(io_lib:format(?SQL_SAVE_CHILD_TOY_FORGE_SLOT, [RoleId, SlotId, StartTime, Status, SelectId])).

get_db_forge_slot_info(RoleId) ->
	db:get_all(io_lib:format(?SQL_SELECT_CHILD_TOY_FORGE_SLOT, [RoleId])).

update_db_toy_forge_slot(RoleId, SlotId, StartTime, Status, SelectId) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_TOY_FORGE_SLOT, [StartTime, Status, SelectId, RoleId, SlotId])).

save_db_child_fashion(RoleId, FashionId, Lv, State) ->
	db:execute(io_lib:format(?SQL_SAVE_CHILD_FASHION, [RoleId, FashionId, Lv, State])).

get_db_child_fashion(RoleId) ->
	db:get_all(io_lib:format(?SQL_SELECT_CHILD_FASHION, [RoleId])).

update_db_fashion_lv(RoleId, FashionId, Lv) ->
	db:execute(io_lib:format(?SQL_UPDATE_FASHION_LV, [Lv, RoleId, FashionId])).

update_db_fashion_state(RoleId, FashionId, State) ->
	db:execute(io_lib:format(?SQL_UPDATE_FASHION_STATE, [State, RoleId, FashionId])).

save_db_toy(RoleId, SuitType, ToyId) ->
	db:execute(io_lib:format(?SQL_SAVE_CHILD_TOY, [RoleId, SuitType, ToyId])).

get_db_toy(RoleId) ->
	db:get_all(io_lib:format(?SQL_SELECT_CHILD_TOY, [RoleId])).

update_db_toy_box(RoleId, BoxLv) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_TOY_BOX_LV, [BoxLv, RoleId])).

save_db_toy_suit(RoleId, SuitType, Status, CollectTime) ->
	db:execute(io_lib:format(?SQL_SAVE_CHILD_TOY_SUIT, [RoleId, SuitType, Status, CollectTime])).

get_db_toy_suit(RoleId) ->
	db:get_all(io_lib:format(?SQL_SELECT_CHILD_TOY_SUIT, [RoleId])).

update_db_toy_suit(RoleId, SuitType, Status, CollectTime) ->
	db:execute(io_lib:format(?SQL_UPDATE_CHILD_TOY_SUIT, [Status, CollectTime, RoleId, SuitType])).

save_db_child_reward(RoleId, ShareReward, YestRank, YestReward) ->
	db:execute(io_lib:format(?SQL_SAVE_CHILD_REWARD, [RoleId, ShareReward, YestRank, YestReward])).

get_db_child_reward(RoleId) ->
	db:get_row(io_lib:format(?SQL_SELECT_CHILD_REWARD, [RoleId])).

delete_db_child_reward() ->
	db:execute(io_lib:format(?SQL_DELETE_CHILD_SHARE_REWARD, [])).