%%%-------------------------------------------------------------------
%%% @doc    孩子基础逻辑
%%% Module  : lib_child.erl
%%% Created : 2020-02-17
%%% @Author : tyl
%%%-------------------------------------------------------------------
-module(lib_child).

-include("common.hrl").
-include("server.hrl").
-include("child.hrl").
-include("role.hrl").
-include("figure.hrl").
-include("goods.hrl").
-include("skill.hrl").
-include("def_goods.hrl").
-include("def_fun.hrl").
-include("def_module.hrl").
-include("predefine.hrl").
-include("errcode.hrl").

-export([
	make_list/2
	,send_msg/3              %% 发送消息
	,send_error/2            %% 发送错误消息

	,get_child_info/1        %% 查询孩子基础信息
	,adopt_child/3           %% 领养孩子
	,rename_child/2          %% 修改名字
	,grow_up_child/4         %% 孩子成长培养
	,upgrade_link_heart/4    %% 同心度培养

	,calc_child_attr/1       %% 计算孩子系统属性总和
	,calc_child_power/1      %% 计算孩子系统战力
	,refresh_attr/2          %% 刷新属性战力

	,add_vote_for_child/2         %% 被点赞者刷新点赞记录(排行榜进程)
	,is_same_srv/2                %% 判断是否跨服点赞(游戏服调用)
	,add_vote_for_child_on_node/3 %% 跨服点赞
	,refresh_vote_count/4         %% 刷新点赞&晒娃次数(玩家进程)
	,change_feed_back_state/3     %% 刷新回赞状态
	,get_vote_role_list/1         %% 获取玩家当天点赞过的玩家列表

	,get_child_skill/1            %% 获取孩子技能信息
	,active_child_skill/2         %% 激活孩子技能
	,upgrade_child_skill/2        %% 升级孩子技能
	,get_skill_sequence/1         %% 根据技能Id获取技能的顺序

	,check_if_active_passive_skill/2   %% 检查是否激活了被动技能
	,get_active_passive_skill/1        %% 获取载具激活的被动技能

	,set_child_follow/1           %% 设置孩子跟随
	,set_vehicle_follow/3         %% 设置载具跟随
	,broadcast_to_scene/1         %% 场景广播
	,update_player_figure/3       %% 更新玩家身上figure数据

	,upgrade_link_heart_with_material/3   %% 使用材料提升同心等级
	,do_upgrade_link_heart/2
	,get_player_link_heart/1  %%获取同心值

	,receive_share_reward/1         %% 领取分享奖励
	,receive_yest_reward/1          %% 领取昨日榜奖励

	%% gm操作
	,gm_change_link_heart_exp/2     %% 增加同心经验值
]).

%% API
%% 查询孩子基础信息
get_child_info(Player) ->
	#player_status{sid = Sid, status_child = StatusChild} = Player,
	#status_child{
		child_name        = ChildName
		,child_sex        = ChildSex
		,child_age_year   = ChildAgeYear
		,child_age_month  = ChildAgeMonth
		,child_age_exp    = ChildAgeExp
		,heart_link_exp   = HeartLinkExp
		,heart_reward     = HeartLinkReward
		,child_power      = ChildPower
		,is_follow        = IsFollow
		,can_carry        = CanCarry
		,adopt_time       = AdoptTime
		,show_off_times   = ShowOffTimes
		,share_reward     = ShareRewardStatus
		,yest_rank        = YestRank
		,yest_reward      = YestRewardStatus
	} = StatusChild,
	ShareRewardStatus1 = change_share_reward_status(ShowOffTimes, ShareRewardStatus),
	YestRewardStatus1  = change_yest_reward_status(YestRank, YestRewardStatus),
	Msg = [ChildName, ChildSex, ChildAgeYear, ChildAgeMonth,
		ChildAgeExp, HeartLinkExp, HeartLinkReward, ChildPower,
		IsFollow, CanCarry, AdoptTime, ShareRewardStatus1, YestRank
		,YestRewardStatus1
	],
	send_msg(Sid, 16501, Msg),
	{ok, Player}.

change_share_reward_status(ShowOffTimes, Status) ->
	case ShowOffTimes =< 0 of
		true -> 0;
		_ ->
			case Status == 0 of
				true -> 1;
				_ -> 2
			end
	end.

change_yest_reward_status(YestRank, Status) ->
	case data_child:get_child_vote_reward_cfg(YestRank) of
		#child_vote_reward_cfg{reward_list = [_|_] = Reward} -> ok;
		_ -> Reward = []
	end,
	case Reward == [] of
		true -> 0;
		_ ->
			case Status == 0 of
				true -> 1;
				_ -> 2
			end
	end.

%% 领养孩子
adopt_child(Player, Sex, IName) ->
	#player_status{sid = Sid, id = RoleId, status_child = StatusChild} = Player,
	#status_child{heart_link_exp = HeartLinkExp, heart_reward = HeartReward, child_sex = OldSex} = StatusChild,
	%% 敏感词检测,允许跟玩家名字相同
	Name = ?IF(IName == "", "小朋友", IName),
	case lib_word:validate_name([width, keyword], Name) of
		true ->
			CheckList = [{has_adopt, OldSex}, {is_name_exit, Name}, {is_sex_true, Sex},
				{is_max_heart_exp, HeartLinkExp}, {has_receive_all_reward, HeartReward}],
			case lib_child_util:check_adopt(CheckList) of
				true ->
					{ok, StatusChild1} = do_adopt_child(Player, Sex, Name),
					#status_child{
						child_name = ChildName, child_sex = ChildSex, child_power = ChildPower, vote_times = VoteTimes
					} = StatusChild1,
					%% 写库
					lib_child_util:save_db_child(RoleId, ChildName, ChildSex, 0, 0, 0,
						HeartLinkExp, HeartReward, VoteTimes, 0, 0, 0, 0, 0, utime:unixtime()),
					Player1 = lib_child_util:save_dict_status_child(StatusChild1, Player),
					NewPlayer = refresh_attr(Player1, adopt_child),
					lib_seven_days_goal:finish_task(RoleId, ?MOD_CHILD, 1, 1, true),
					send_msg(Sid, 16502, [ChildName, ChildSex, 0, 0, 0, ChildPower]);
				{false, Res} ->
					send_error(Sid, Res),
					NewPlayer = Player
			end,
			NewPlayer;
		{false, Err} ->
			ErrCode = change_error_code(Err),
			send_error(Sid, ErrCode),
			Player
	end.

%% 修改名字
rename_child(Player, Name) ->
	#player_status{id = RoleId, sid = Sid, status_child = StatusChild} = Player,
	%% 敏感词检测
	case lib_word:validate_name([width, keyword], Name) of
		true ->
			CheckList = [{has_adopt, StatusChild#status_child.child_sex},
				{is_same_name, Name, StatusChild#status_child.child_name},
				{is_name_exit, Name}],
			case lib_child_util:check_rename(CheckList) of
				true ->
					#child_constant_cfg{constant = CostList} = data_child:get_child_kv_cfg(rename_cost),
					case lib_goods_api:cost_object_list_with_check(Player, CostList, child_rename_cost, "") of
						{true, Player1, _} ->
							NewStatusChild = StatusChild#status_child{child_name = Name},
							%% 写库
							lib_child_util:update_db_child_name(RoleId, Name),
							send_msg(Sid, 16503, [Name]),
							%% 修改榜单数据
							mod_child_vote_mgr:change_child_name(RoleId, Name),
							NewPlayer = lib_child_util:save_dict_status_child(NewStatusChild, Player1);
						{false, ErrCode, _Player1} ->
							send_error(Sid, ErrCode),
							NewPlayer = Player
					end;
				{false, Res} ->
					send_error(Sid, Res),
					NewPlayer = Player
			end;
		{false, Err} ->
			ErrCode = change_error_code(Err),
			send_error(Sid, ErrCode),
			NewPlayer = Player
	end,
	{ok, NewPlayer}.

%% 孩子成长培养
grow_up_child(Player, IsAuto, GoodId, GoodNum) ->
	#player_status{sid = Sid, status_child = StatusChild} = Player,
	#status_child{
		child_age_year = AgeYear, child_age_month = AgeMonth,
		child_sex = ChildSex, is_follow = IsFollow
	} = StatusChild,
	case IsAuto == 1 of
		true ->
			CheckList = [{has_adopt, ChildSex},
				{is_max_age_year_month, AgeYear, AgeMonth},
				{has_grow_up_material}];
		_ ->
			CheckList = [{has_adopt, ChildSex},
				{is_max_age_year_month, AgeYear, AgeMonth},
				{is_grow_up_material, GoodId}, {is_good_enough, GoodId, GoodNum}
			]
	end,
	case lib_child_util:check_grow_up(CheckList) of
		true ->
			case do_grow_up(Player, IsAuto, GoodId, GoodNum) of
				{true, Player1} ->
					#player_status{status_child = NewStatusChild} = Player1,
					#status_child{
						child_age_year = NewAgeYear, child_age_month = NewAgeMonth,
						child_age_exp  = NewAgeExp
					} = NewStatusChild,
					case IsFollow of
						1 ->
							%% 更新玩家身上数据
							Player2 = update_player_figure(child, Player1, [1, ChildSex, NewAgeMonth]),
							%% 更新场景数据
							mod_scene_agent:update(Player2, [{follow_child, [1, ChildSex, NewAgeMonth]}]),
							%% 场景广播
							broadcast_to_scene(Player2);
						_ ->
							Player2 = Player1
					end,
					%% 激活玩具位
					% {ok, ToyPlayer} = lib_child_items:check_if_active_toy_slot(Player1, ?SLOT_OPEN_TYPE_CHILD_AGE),
					%% 完成任务
					FTaskPlayer = lib_child_task:finish_grow_up_child(Player2),
					send_msg(Sid, 16504, [NewAgeYear, NewAgeMonth, NewAgeExp]),
					ActPlayer = custom_act_personal:event_child_group_up(FTaskPlayer, Player),
					custom_act_mobilize:update_mobilize_task(ActPlayer, babyup, NewAgeMonth - AgeMonth, false),
					{ok, ActPlayer};
				{false, ErrCode, _Player1} ->
					send_error(Sid, ErrCode),
					{ok, Player}
			end;
		{false, Res} ->
			send_error(Sid, Res),
			{ok, Player}
	end.

%% 孩子同心度培养
upgrade_link_heart(Player, Type, Id, _Num) ->
	#player_status{status_child = StatusChild} = Player,
	#status_child{child_sex = ChildSex} = StatusChild,
	%% 如果已经领养了孩子，不能进行同心度培养
	case ChildSex > 0 of
		true ->
			send_error(Player#player_status.sid, ?ERRCODE(err165_child_has_adopt)),
			{ok, Player};
		_ ->
			case Type of
				?TYPE_TASK -> % 任务经验领取
					{ok, NewPlayer} = lib_child_task:receive_daily_task_exp(Player, Id),
					{ok, NewPlayer};
				% ?TYPE_MATERIALS ->
				%	{ok, NewPlayer} = upgrade_link_heart_with_material(Player, Id, Num),
				%	{ok, NewPlayer};
				?TYPE_USE_BGOLD ->
					{ok, NewPlayer} = quick_upgrade_link_heart_with_money(Player),
					{ok, NewPlayer};
				_ ->
					send_error(Player#player_status.sid, ?ERRCODE(err165_child_upgrade_link_heart_type_err)),
					{ok, Player}
			end
	end.

%% 判断是否跨服点赞(游戏服调用)
is_same_srv(ServerId, BeVoteId) ->
	BeVotedSrvId = mod_player_create:get_serid_by_id(BeVoteId),
	case config:get_merge_server_ids() of
		[] -> ServerId =:= BeVotedSrvId;
		MergeSerIds ->
			case lists:member(BeVotedSrvId, MergeSerIds) of
				false -> false;
				_ -> true
			end
	end.

%% 跨服点赞
add_vote_for_child_on_node(_BeVotedSrvId, BeVotedId, VoteInfo) ->
	MFA = {
		lib_player, apply_cast,
		[BeVotedId, ?APPLY_CAST_SAVE, ?HAND_OFFLINE, ?MODULE, add_vote_for_child, [VoteInfo]]
	},
	Node = clusters_center:get_node_by_role_id(BeVotedId),
	clusters_center:apply_cast(Node, MFA).

%% 点赞孩子,被点赞者刷新点赞记录
add_vote_for_child(Player, VoteInfo) ->
	#player_status{id = BeVoteRoleId, status_child = StatusChild} = Player,
	#status_child{be_voted_log = BeVotedLog, child_name = ChildName, child_sex = ChildSex} = StatusChild,
	[VoteRoleId, VoteName, CanAdd] = VoteInfo,
	case ChildSex > 0 of
		false ->
			{ok, Bin} = pt_165:write(16500, [?ERRCODE(err165_opp_not_adopt_child)]),
			lib_server_send:send_to_uid(VoteRoleId, Bin),
			{ok, Player};
		true  ->
			case lists:keyfind(VoteRoleId, #child_vote_log.vote_id, BeVotedLog) of
				#child_vote_log{} when CanAdd == false ->
					{ok, Bin} = pt_165:write(16500, [?ERRCODE(err165_has_vote_for_this_child)]),
					lib_server_send:send_to_uid(VoteRoleId, Bin),
					{ok, Player};
				_ ->
					NowTime = utime:unixtime(),
					ChildVoteLog = #child_vote_log{
						vote_id          = VoteRoleId,
						vote_name        = VoteName,
						time             = NowTime,
						feed_back_status = ?FEED_BACK_NOT
					},
					%% 点赞榜+1
					mod_child_vote_mgr:add_child_vote_count(VoteRoleId, BeVoteRoleId, ChildName),
					NewBeVoteLog = lists:keystore(
						VoteRoleId, #child_vote_log.vote_id, BeVotedLog, ChildVoteLog),
					NewStatusChild = StatusChild#status_child{
						be_voted_log   = NewBeVoteLog
					},
					%% 存库
					F = fun() ->
						lib_child_util:save_db_child_vote_log(
							BeVoteRoleId, VoteRoleId, VoteName, NowTime, ChildVoteLog#child_vote_log.feed_back_status
						),
						% lib_child_util:update_db_be_voted_count(BeVoteRoleId, BeVotedCount+1),
						ok
					    end,
					case F() of
						ok ->
							NewPlayer = lib_child_util:save_dict_status_child(NewStatusChild, Player),
							lib_offline_api:update_offline_ps(BeVoteRoleId, [{child_vote_log, NewBeVoteLog}]), %% 更新离线数据
							{ok, NewPlayer};
						_ ->
							{ok, Player}
					end
			end
	end.

%% 获取孩子技能信息
get_child_skill(Player) ->
	#player_status{sid = Sid, status_child = StatusChild} = Player,
	case StatusChild#status_child.child_sex > 0 of
		true ->
			#status_child{active_skill = ActiveSkill} = StatusChild,
			send_msg(Sid, 16512, [ActiveSkill]);
		_ ->
			send_error(Sid, ?ERRCODE(err165_child_not_adopt))
	end.

%% 激活孩子技能
active_child_skill(Player, SkillId) ->
	#player_status{sid = Sid, status_child = StatusChild, figure = Figure} = Player,
	#status_child{
		child_sex       = ChildSex,
		child_age_year  = ChildAgeYear,
		active_skill    = SkillList
	} = StatusChild,
	#child_constant_cfg{constant = NeedLv} = data_child:get_child_kv_cfg(skill_open_stage),
	CheckList = [
		{has_adopt_child, ChildSex}, {is_child_skill, SkillId},
		{is_reach_skill_open_lv, NeedLv, ChildAgeYear},
		{has_active_skill, SkillId, SkillList},
		{has_pre_skill_active, SkillId, SkillList},
		{is_power_reach, SkillId, Figure#figure.power},
		{is_active_material_enough, SkillId}
	],
	case lib_child_util:check_active_skill(CheckList) of
		true ->
			case do_active_skill(Player, SkillId) of
				{true, NewPlayer} ->
					send_msg(Sid, 16513, [SkillId, 1]);
				{false, ErrCode} ->
					send_error(Sid, ErrCode),
					NewPlayer = Player
			end,
			{ok, NewPlayer};
		{false, Res} ->
			send_error(Sid, Res),
			{ok, Player}
	end.

%% 升级孩子技能
upgrade_child_skill(Player, SkillId) ->
	#player_status{sid = Sid, status_child = StatusChild, figure = Figure} = Player,
	#status_child{child_sex = ChildSex, active_skill = SkillList} = StatusChild,
	SkillInfo =
	case lists:keyfind(SkillId, 1, SkillList) of
		{_, _} = TSkillInfo -> TSkillInfo;
		_                   -> {SkillId, 0}
	end,
	CheckList = [
		{has_adopt_child, ChildSex}, {is_child_skill, SkillId},
		{has_active_skill, SkillId, SkillList}, {is_max_skill, SkillInfo},
		{is_power_reach, SkillInfo, Figure#figure.power},
		{is_upgrade_material_enough, SkillInfo}
	],
	case lib_child_util:check_upgrade_skill(CheckList) of
		true ->
			case do_upgrade_child_skill(Player, SkillInfo) of
				{true, NewPlayer, NewSkillLv} ->
					send_msg(Sid, 16513, [SkillId, NewSkillLv]);
				{false, ErrCode} ->
					send_error(Sid, ErrCode),
					NewPlayer = Player
			end,
			{ok, NewPlayer};
		{false, Res} ->
			send_error(Sid, Res),
			{ok, Player}
	end.

%% 根据技能Id获取技能的顺序
get_skill_sequence(SkillId) ->
	SeqList = 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 = [{ActiveSkill, _}]}
				when ActiveSkill == SkillId ->
				[Seq|TList];
			_ -> TList
		end end,
	SkillSeq = case lists:foldl(F, [], SeqList) of
		           [TSeq|_] -> TSeq;
		           _        -> 0
	           end,
	SkillSeq.

%% 登录刷新(4点之前的才刷新)当天点赞&晒娃次数
refresh_vote_count(RoleId, RefreshTime, VoteTimes, ShowOffTimes) ->
	DailyTime = utime:unixtime({4,0,0}),
	{NewVoteTimes, NewShowOffTimes} =
	case RefreshTime < DailyTime of
		true ->
			lib_child_util:update_db_vote_count(
				RoleId, 0, 0
			),
			{0, 0};
		_    -> {VoteTimes, ShowOffTimes}
	end,
	{NewVoteTimes, NewShowOffTimes}.

%% 更新回赞状态
change_feed_back_state(LogBeVotedId, LogVoteId, BeVotedLogs) ->
	case lists:keyfind(LogVoteId, #child_vote_log.vote_id, BeVotedLogs) of
		#child_vote_log{feed_back_status = FeedBackStatus} = VoteLog
			when FeedBackStatus =< ?FEED_BACK ->
			NewVoteLog = VoteLog#child_vote_log{feed_back_status = ?FEED_BACK},
			% 存库
			lib_child_util:update_db_child_vote_back_status(LogBeVotedId, LogVoteId, ?FEED_BACK),
			NewBeVotedLogs = lists:keystore(LogVoteId, #child_vote_log.vote_id, BeVotedLogs, NewVoteLog);
		_ ->
			NewBeVotedLogs = BeVotedLogs
	end,
	NewBeVotedLogs.

%% 获取玩家当天点赞过的玩家列表
get_vote_role_list(#player_status{id = RoleId, sid = Sid, status_child = StatusChild} = _Player) ->
	#status_child{
		child_sex      = ChildSex,
		vote_role_list = VoteRoleList} = StatusChild,
	case ChildSex > 0 of
		true ->
			SFun = fun(TRoleId, TList) ->
				TTimes = lib_daily:get_count(RoleId, ?MOD_CHILD, 1, TRoleId),
				[{TRoleId, 1+min(1, TTimes)}|TList]
				end,
			SendVoteList = lists:foldl(SFun, [], VoteRoleList),
			send_msg(Sid, 16519, [SendVoteList]);
		_ ->
			send_error(Sid, ?ERRCODE(err165_child_not_adopt))
	end.

%% 孩子场景跟随
set_child_follow(#player_status{sid = Sid, id = RoleId, status_child = StatusChild} = Player) ->
	#status_child{
		child_sex    = ChildSex,
		is_follow    = IsFollow,
		child_age_month = AgeMonth
	} = StatusChild,
	case ChildSex > 0 of
		true ->
			%% 襁褓期不能跟随
			case data_child:get_child_kv_cfg(baby_month) of
				#child_constant_cfg{constant = NeedMonth} -> ok;
				_ -> NeedMonth = ?FOLLOW_DEFAULT_MONTH
			end,
			case AgeMonth >= NeedMonth of
				true ->
					NFollowStatus = ?IF(IsFollow == ?FOLLOW,  ?NOT_FOLLOW, ?FOLLOW),
					NewStatusChild = StatusChild#status_child{is_follow = NFollowStatus},
					lib_child_util:update_db_child_follow_status(RoleId, NFollowStatus),
					NewPlayer = lib_child_util:save_dict_status_child(NewStatusChild, Player),
					%% 更新玩家身上数据
					NewPlayer1 = update_player_figure(child, NewPlayer, [NFollowStatus, ChildSex, AgeMonth]),
					%% 更新场景数据
					mod_scene_agent:update(NewPlayer1, [{follow_child, [NFollowStatus, ChildSex, AgeMonth]}]),
					%% 场景广播
					broadcast_to_scene(NewPlayer1),
					send_msg(Sid, 16516, [NFollowStatus]),
					NewPlayer1;
				_ ->
					send_error(Sid, ?ERRCODE(err165_follow_month_not_enough)),
					Player
			end;
		_ ->
			send_error(Sid, ?ERRCODE(err165_child_not_adopt)),
			Player
	end.

%% 载具场景跟随
set_vehicle_follow(Player, Type, VehicleId) ->
	#player_status{sid = Sid, id = RoleId, status_child = StatusChild} = Player,
	#status_child{
		child_sex    = ChildSex,
		vehicle      = VehicleList,
		show_vehicle = ShowVehicle} = StatusChild,
	case ChildSex > 0 of
		true ->
			Return =
			case Type of
				%% 跟随
				1 ->
					case lists:keyfind(VehicleId, 1, VehicleList) of
						{_, _} ->
							NFollowVehicle = VehicleId,
							TStatusChild = StatusChild#status_child{show_vehicle = NFollowVehicle},
							{true, TStatusChild, NFollowVehicle};
						_ ->
							{false, StatusChild, ShowVehicle}
					end;
				%% 取消跟随
				2 ->
					case lists:keyfind(VehicleId, 1, VehicleList) of
						{_, _} ->
							TStatusChild = StatusChild#status_child{show_vehicle = 0},
							{true, TStatusChild, 0};
						_ ->
							{false, StatusChild, ShowVehicle}
					end
			end,
			case Return of
				{true, NewStatusChild, NShowVehicle} ->
					lib_child_util:update_db_vehicle_follow_status(RoleId, NShowVehicle),
					NewPlayer = lib_child_util:save_dict_status_child(NewStatusChild, Player),
					%% 更新玩家身上数据
					NewPlayer1 = update_player_figure(child_vehicle, NewPlayer, NShowVehicle),
					%% 更新场景数据
					mod_scene_agent:update(NewPlayer1, [{child_vehicle, NShowVehicle}]),
					%% 场景广播
					broadcast_to_scene(NewPlayer1),
					send_msg(Sid, 16517, [Type, NShowVehicle]),
					NewPlayer1;
				_ ->
					send_error(Sid, ?ERRCODE(err165_child_vehicle_not_active)),
					Player
			end;
		_ ->
			send_error(Sid, ?ERRCODE(err165_child_not_adopt)),
			Player
	end.

%% 更新玩家figure中的孩子信息
update_player_figure(child, Player, IfShow) ->
	#player_status{figure = Figure, id = _RoleId} = Player,
	NewFigure = Figure#figure{baby_if_show = IfShow},
	Player#player_status{figure = NewFigure};
update_player_figure(child_vehicle, Player, VehicleInfo) ->
	#player_status{figure = Figure} = Player,
	NewFigure = Figure#figure{baby_vehicle = VehicleInfo},
	Player#player_status{figure = NewFigure};
update_player_figure(child_fashion, Player, FashionInfo) ->
	#player_status{figure = Figure} = Player,
	NewFigure = Figure#figure{baby_model = FashionInfo},
	Player#player_status{figure = NewFigure}.

%% 广播给场景玩家
broadcast_to_scene(Player) ->
	#player_status{id = RoleId, scene = Scene, scene_pool_id = PoolId,
		copy_id = CopyId, x = X, y = Y, status_child = StatusChild
	} = Player,
	#status_child{
		is_follow        = IsFollow,
		child_sex        = ChildSex,
		child_age_month  = AgeMonth,
		show_vehicle     = VehicleId,
		dress_up_fashion = FashionList} = StatusChild,
	{ok, BinData} = pt_165:write(16518, [RoleId, ChildSex, AgeMonth, IsFollow, VehicleId, FashionList]),
	lib_server_send:send_to_area_scene(Scene, PoolId, CopyId, X, Y, BinData).

%% --------------------- builtin_function --------------------------
trans_status_child(StatusChild) when is_record(StatusChild, status_child) -> StatusChild;
trans_status_child(_) -> #status_child{}.

do_adopt_child(Player, Sex, Name) ->
	#player_status{status_child = StatusChild} = Player,
	StatusChild1 = trans_status_child(StatusChild),
	InitAgeYear = 0, InitAgeMonth = 0,
	#child_grow_up_cfg{attr_list = AttrList} =
		data_child:get_child_grow_up_cfg(InitAgeYear, InitAgeMonth),
	ChildName = case Name == "" of
					true -> "小朋友";
					_ -> Name
	            end,
	% CanCarry = lib_child_items:calc_can_carry_weight(0, 0, [], []),
	NewStatusChild = StatusChild1#status_child{
		child_name       = ChildName
		,child_sex       = Sex
		,child_age_year  = InitAgeYear
		,child_age_month = InitAgeMonth
		,attr_list       = AttrList
		,child_power     = calc_child_power(AttrList)
		% ,can_carry       = CanCarry
	},
	{ok, NewStatusChild}.

do_grow_up(Player, IsAuto, GoodId, GoodNum) ->
	#player_status{id = RoleId, status_child = StatusChild} = Player,
	#status_child{
		child_age_year = AgeYear, child_age_month = AgeMonth,
		child_age_exp  = AgeExp % , vehicle = VehicleL, fashion_list = FashionL
	} = StatusChild,
	#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 IsAuto == 1 of
		true -> % 自动升级
			[{_, OwnNum1}] = lib_goods_api:get_goods_num(Player, [LowFeedId]),
			[{_, OwnNum2}] = lib_goods_api:get_goods_num(Player, [MidFeedId]),
			[{_, OwnNum3}] = lib_goods_api:get_goods_num(Player, [HighFeedId]),
			AddExpSum = AddExp1*OwnNum1 + AddExp2*OwnNum2 + AddExp3*OwnNum3,
			%% 扣除材料
			CostList  = [{?TYPE_GOODS, LowFeedId, OwnNum1}, {?TYPE_GOODS, MidFeedId, OwnNum2}, {?TYPE_GOODS, HighFeedId, OwnNum3}],
			CostList1 = [{GoodType, GoodTypeId, OwnNum} || {GoodType, GoodTypeId, OwnNum} <- CostList, OwnNum > 0];
		_ -> % 非自动升级
			CostMaterials = [{LowFeedId, AddExp1}, {MidFeedId, AddExp2}, {HighFeedId, AddExp3}],
			{_FeedId, AddExp} = lists:keyfind(GoodId, 1, CostMaterials),
			[{_, OwnNum}] = lib_goods_api:get_goods_num(Player, [GoodId]),
			CostNum = ?IF(OwnNum >= GoodNum, GoodNum, OwnNum),
			AddExpSum = AddExp*CostNum,
			CostList1 = [{?TYPE_GOODS, GoodId, CostNum}]
	end,
	{AgeYear1, AgeMonth1, AgeExp1} = do_calc_next_age(AgeYear, AgeMonth, AgeExp, AddExpSum),
	% CanCarry = lib_child_items:calc_can_carry_weight(AgeYear1, AgeMonth1, VehicleL, FashionL),
	NewStatusChild = StatusChild#status_child{
		child_age_year = AgeYear1, child_age_month = AgeMonth1,
		child_age_exp  = AgeExp1 % , can_carry = CanCarry
	},
	case lib_goods_api:cost_object_list_with_check(Player, CostList1, child_grow_up_cost, "") of
		{true, Player1, _} ->
			%% 写库
			lib_child_util:update_db_child_age(RoleId, AgeYear1, AgeMonth1, AgeExp1),
			%% 日志
			lib_log_api:log_child_upgrade(RoleId, AgeYear, AgeMonth, AgeYear1, AgeMonth1,
				CostList1),
			NewPlayer     = lib_child_util:save_dict_status_child(NewStatusChild, Player1),
			RefreshPlayer = refresh_attr(NewPlayer, child_grow_up),
			AgeMonth1 =/= AgeMonth
				andalso mod_scene_agent:update(RefreshPlayer, [{battle_attr, RefreshPlayer#player_status.battle_attr}]),
			{true, RefreshPlayer};
		{false, ErrCode, _Player1} ->
			{false, ErrCode, Player}
	end.

do_calc_next_age(AgeYear, AgeMonth, AgeExp, 0) -> {AgeYear, AgeMonth, AgeExp};
do_calc_next_age(AgeYear, AgeMonth, AgeExp, AddExpSum) ->
	case data_child:get_child_grow_up_cfg(AgeYear, AgeMonth) of
		% #child_grow_up_cfg{next_year = NextYear} when NextYear == 0 -> % 最高等级
		%	{AgeYear, AgeMonth, AgeExp + AddExpSum};
		#child_grow_up_cfg{need_exp = NeedExp} ->
			case (AgeExp + AddExpSum) >= NeedExp of
				true ->
					do_calc_next_age(AgeYear, AgeMonth+1, 0, (AgeExp + AddExpSum)-NeedExp);
				_ ->
					{AgeYear, AgeMonth, AgeExp + AddExpSum}
			end;
		_ ->  % 晋升到下一年走这里
			case data_child:get_child_grow_up_cfg(AgeYear+1, AgeMonth) of
				#child_grow_up_cfg{need_exp = NeedExp} ->
					case (AgeExp + AddExpSum) >= NeedExp of
						true ->
							do_calc_next_age(AgeYear+1, AgeMonth+1, 0, (AgeExp + AddExpSum)-NeedExp);
						_ ->
							{AgeYear+1, AgeMonth, AgeExp + AddExpSum}
					end;
				_ -> % 上一年月是最高等级
					{AgeYear, AgeMonth-1, AgeExp+AddExpSum}
			end
	end.

upgrade_link_heart_with_material(Player, Id, Num) ->
	#player_status{id = RoleId, sid = Sid, status_child = StatusChild} = Player,
	#child_constant_cfg{constant =[{_GoodId, AddExp}]} = data_child:get_child_kv_cfg(heart_feed),
	CheckList = [{is_max_heart_exp, StatusChild#status_child.heart_link_exp},
		{is_adopt, StatusChild#status_child.child_sex}, {is_upgrade_material, Id},
		{is_material_enough, Id, Num}
	],
	case lib_child_util:check_upgrade_link_heart(CheckList, Player) of
		{true, TPlayer} ->
			lib_goods_api:cost_object_list(Player, [{0, Id, Num}], goods_use, ""),
			[{_, OwnNum}] = lib_goods_api:get_goods_num(Player, [Id]),
			CostNum   = min(OwnNum, Num),
			AddExpSum = CostNum*AddExp,
			NewStatusChild = do_upgrade_link_heart(StatusChild, AddExpSum),
			#status_child{
				heart_link_exp   = NewHeartLinkExp, heart_reward = HeartReward,
				vote_times = VoteTimes
			} = NewStatusChild,
			lib_child_util:save_db_child(RoleId, "", 0, 0, 0, 0,
				NewHeartLinkExp, HeartReward, VoteTimes, 0, 0, 0, 0, 0, 0),
			% lib_log_api:log_child_upgrade(RoleId, NewHeartLinkLv, NewHeartLinkExp),
			NewPlayer   = lib_child_util:save_dict_status_child(NewStatusChild, TPlayer),
			% {ok, Player2} = lib_child_items:check_if_active_toy_slot(Player1, ?SLOT_OPEN_TYPE_CHILD_AGE),
			% NewPlayer = refresh_attr(Player1, upgrade_link_heart),
			send_msg(Sid, 16506, [NewHeartLinkExp]),
			lib_log_api:log_child_link_heart(RoleId, 2, 0, [{?TYPE_GOODS, Id, Num}], AddExpSum,
				StatusChild#status_child.heart_link_exp, NewStatusChild#status_child.heart_link_exp),
			lib_task_api:child_heart(NewPlayer,NewStatusChild#status_child.heart_link_exp),
			{use_child_upgrade_material, NewPlayer, CostNum};
		{false, Res} ->
			send_error(Sid, Res),
			{fail, Res}
	end.

quick_upgrade_link_heart_with_money(Player) ->
	#player_status{id = RoleId, sid = Sid, status_child = StatusChild} = Player,
	{_MaxExp, NeedExp} = calc_need_exp(StatusChild#status_child.heart_link_exp),
	CheckList = [{is_max_heart_exp, StatusChild#status_child.heart_link_exp}, {open_day},
		{is_adopt, StatusChild#status_child.child_sex}, {is_money_enough, NeedExp}
	],
	case lib_child_util:check_upgrade_link_heart(CheckList, Player) of
		{true, TPlayer} ->
			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 = Price} -> ok;
				_ -> Price = 0
			end,
			CostMoney = calc_cost_money(Player, Price*NeedExp),
			case lib_goods_api:cost_object_list(TPlayer, CostMoney, adopt_child, "") of
				{true, Player1} ->
					NewStatusChild = do_upgrade_link_heart(StatusChild, NeedExp),
					#status_child{
						heart_link_exp = NewHeartLinkExp, heart_reward = HeartReward,
						vote_times = VoteTimes
					} = NewStatusChild,
					lib_child_util:save_db_child(RoleId, "", 0, 0, 0, 0,
						NewHeartLinkExp, HeartReward, VoteTimes, 0, 0, 0, 0, 0, 0),
					NewPlayer = lib_child_util:save_dict_status_child(NewStatusChild, Player1),
					% {ok, Player2} = lib_child_items:check_if_active_toy_slot(Player1, ?SLOT_OPEN_TYPE_CHILD_AGE),
					%NewPlayer = refresh_attr(Player2, upgrade_link_heart),
					send_msg(Sid, 16506, [NewHeartLinkExp]),
					lib_log_api:log_child_link_heart(RoleId, 2, 0, CostMoney, NeedExp,
						StatusChild#status_child.heart_link_exp, NewStatusChild#status_child.heart_link_exp),
					lib_task_api:child_heart(NewPlayer,NewStatusChild#status_child.heart_link_exp),
					ta_agent_fire:child_heart(NewPlayer,
						["购买", 0, Price*NeedExp, NeedExp, NewStatusChild#status_child.heart_link_exp]
					),
					{ok, NewPlayer};
				_ ->
					send_error(Sid, ?ERRCODE(money_not_enough)),
					{ok, Player}
			end;
		{false, Res} ->
			send_error(Sid, Res),
			{ok, Player}
	end.

calc_need_exp(NowExp) ->
	MaxExp = data_child:get_child_max_heart_link_exp(),
	{MaxExp, max(0, MaxExp - NowExp)}.

calc_cost_money(Player, CostMoney) ->
	#player_status{gold = _Gold, bgold = BGold} = Player,
	CostList =
	case BGold >= CostMoney of
		true -> [{?TYPE_BGOLD, 0, CostMoney}];
		_ ->
			NeedGold = CostMoney - BGold,
			TCostList = [{?TYPE_BGOLD, 0, BGold}, {?TYPE_GOLD, 0, NeedGold}],
			[{Type, GoodsId, Num}||{Type, GoodsId, Num}<-TCostList, Num =/= 0]
	end,
	CostList.

do_upgrade_link_heart(StatusChild, AddExp) ->
	#status_child{
		heart_link_exp   = HeartLinkExp
	} = StatusChild,
	NewStatusChild = StatusChild#status_child{
		heart_link_exp   = HeartLinkExp + AddExp
	},
	NewStatusChild.

do_active_skill(#player_status{id = RoleId, status_child = StatusChild} = Player, SkillId) ->
	#status_child{active_skill = SkillList, passive_skill = PassiveSkill} = StatusChild,
	Sequence = get_skill_sequence(SkillId),
	#child_skill_cfg{active_cost = CostList} = data_child:get_child_skill_cfg(Sequence, 1),
	case lib_goods_api:cost_object_list_with_check(Player, CostList, child_active_skill_cost, "") of
		{true, Player1, _} ->
			AddPassive = get_passive_skill(Sequence, SkillId, 1),
			case [TSkill||{TSkill, _}<- AddPassive] of
				[Passive] -> NewPassiveSkill = [Passive|lists:delete(Passive, PassiveSkill)];
				_ -> NewPassiveSkill = PassiveSkill
			end,
			%% 被动都放在技能列表里面吧，拿的时候再筛选
			NewSkillList = lists:keystore(SkillId, 1, SkillList, {SkillId, 1}),
			NewStatusChild  = StatusChild#status_child{active_skill = NewSkillList, passive_skill = NewPassiveSkill},
			NewPlayer = lib_child_util:save_dict_status_child(NewStatusChild, Player1),
			%% 计算属性
			RefreshPlayer = refresh_attr(NewPlayer, active_child_skill),
			%% 存库
			lib_child_util:save_db_child_skill(RoleId, SkillId, 1),
			%% 日志
			lib_log_api:log_child_skill(RoleId, SkillId, 0, 1, CostList),
			handle_skill_achievement(Player, NewSkillList),
			%% 更新场景数据
			case AddPassive =/= [] of
				true ->
					mod_scene_agent:update(RefreshPlayer, [{passive_skill, AddPassive},{battle_attr, RefreshPlayer#player_status.battle_attr}]);
				_ ->
					mod_scene_agent:update(RefreshPlayer, [{battle_attr, RefreshPlayer#player_status.battle_attr}])
			end,
			case CostList of
				[{_, CostGoods, CostNum}|_] -> ok;
				_ -> CostGoods = 0, CostNum = 0
			end,
			ta_agent_fire:child_skill(RefreshPlayer, [SkillId, 1, CostGoods, CostNum]),
			{true, RefreshPlayer};
		{false, ErrCode, _Player2} ->
			{false, ErrCode}
	end.

%% 累计激活技能成就
handle_skill_achievement(Player, ActiveSkills) ->
	lib_achievement_api:child_skill_event(Player, erlang:length(ActiveSkills)),
	ok.

do_upgrade_child_skill(	#player_status{id = RoleId, status_child = StatusChild} = Player, SkillInfo) ->
	#status_child{active_skill = SkillList, passive_skill = PassiveSkill} = StatusChild,
	{SkillId, PreLv} = SkillInfo,
	NewSkillLv = PreLv + 1,
	Sequence = get_skill_sequence(SkillId),
	#child_skill_cfg{active_cost = CostList} = data_child:get_child_skill_cfg(Sequence, NewSkillLv),
	case lib_goods_api:cost_object_list_with_check(Player, CostList, child_upgrade_skill_cost, "") of
		{true, Player1, _} ->
			NewSkillList = lists:keystore(SkillId, 1, SkillList, {SkillId, NewSkillLv}),
			AddPassive   = get_passive_skill(Sequence, SkillId, NewSkillLv),
			case lists:member(SkillId, PassiveSkill) of
				true -> NewPassiveSkill = PassiveSkill;
				_    -> NewPassiveSkill = PassiveSkill ++ [TSkill||{TSkill, _}<- AddPassive]
			end,
			NewStatusChild = StatusChild#status_child{active_skill = NewSkillList, passive_skill = NewPassiveSkill},
			NewPlayer = lib_child_util:save_dict_status_child(NewStatusChild, Player1),
			%% 计算属性
			RefreshPlayer = refresh_attr(NewPlayer, upgrade_child_skill),
			%% 存库
			lib_child_util:update_db_child_skill(RoleId, SkillId, NewSkillLv),
			%% 日志
			lib_log_api:log_child_skill(RoleId, SkillId, PreLv, NewSkillLv, CostList),
			%% 更新场景信息
			case AddPassive =/= [] of
				true ->
					mod_scene_agent:update(RefreshPlayer, [{passive_skill, AddPassive},{battle_attr, RefreshPlayer#player_status.battle_attr}]);
				_ ->
					mod_scene_agent:update(RefreshPlayer, [{battle_attr, RefreshPlayer#player_status.battle_attr}])
			end,
			case CostList of
				[{_, CostGoods, CostNum}|_] -> ok;
				_ -> CostGoods = 0, CostNum = 0
			end,
			ta_agent_fire:child_skill(RefreshPlayer, [SkillId, NewSkillLv, CostGoods, CostNum]),
			{true, RefreshPlayer, NewSkillLv};
		{false, ErrCode, _Player2} ->
			{false, ErrCode}
	end.
%% -----------------------------------------------
%% 技能相关
check_if_active_passive_skill(VehicleId, Stage) ->
	case data_child:get_child_vehicle_cfg(VehicleId, Stage) of
		#child_vehicle_cfg{active_skill = PassiveSkill} when is_integer(PassiveSkill), PassiveSkill > 0 ->
			PassiveSkill;
		_ ->
			0
	end.

%% 获取载具激活的被动技能
get_active_passive_skill(VehicleList) ->
	F = fun({VehicleId, Stage}, TSkillList) ->
		PassiveSkills = do_get_active_passive_skill(VehicleId, 0, Stage, []),
		lists:append(PassiveSkills, TSkillList)
	end,
	lists:foldl(F, [], VehicleList).

do_get_active_passive_skill(VehicleId, Stage, Stage, PassiveSkills) ->
	case check_if_active_passive_skill(VehicleId, Stage) of
		PassiveSkill when PassiveSkill > 0 ->
			NewPassiveSkills = ?IF(lists:member(PassiveSkill, PassiveSkills) == true, PassiveSkills, [PassiveSkill|PassiveSkills]),
			NewPassiveSkills;
		_ ->
			PassiveSkills
	end;
do_get_active_passive_skill(VehicleId, TStage, Stage, PassiveSkills) ->
	case check_if_active_passive_skill(VehicleId, TStage) of
		PassiveSkill when PassiveSkill > 0 ->
			NewPassiveSkills = ?IF(lists:member(PassiveSkill, PassiveSkills) == true, PassiveSkills, [PassiveSkill|PassiveSkills]),
			do_get_active_passive_skill(VehicleId, TStage + 1, Stage, NewPassiveSkills);
		_ ->
			do_get_active_passive_skill(VehicleId, TStage + 1, Stage, PassiveSkills)
	end.

%% 获取技能培养激活的被动技能
get_passive_skill(Sequence, _SkillId, Lv) ->
	case data_child:get_child_skill_cfg(Sequence,Lv) of
		#child_skill_cfg{active_skill = [{TSkill, TLv}] = SkillL} ->
			case data_skill:get(TSkill, TLv) of
				#skill{type = ?SKILL_TYPE_PASSIVE} -> SkillL;
				_ -> []
			end;
		_ ->
			[]
	end.

%% -----------------------------------------------
%% 属性相关
%% 计算战力
calc_child_power(AttrList) ->
	NewAttrList = lib_player_attr:partial_attr_convert(AttrList),
	AttrR = attr_conv:to_attr_record(NewAttrList),
	Power = lib_player_attr:calc_attr_power(AttrR),
	Power.

%% 计算技能属性
calc_skill_attr(ActiveSkill, PassiveSkill) ->
	F = fun({SkillId, Lv}, {TAttrList, TSkillList}) ->
		Sequence = get_skill_sequence(SkillId),
		case data_child:get_child_skill_cfg(Sequence, Lv) of
			#child_skill_cfg{add_attr_list = AttrList, active_skill = TSkill} ->
				{util:combine_list(AttrList ++ TAttrList), TSkill++TSkillList};
			_ ->
				{TAttrList, TSkillList}
		end
	end,
	{SkillAttr, SkillList} = lists:foldl(F, {[],[]}, ActiveSkill),
	PassiveSkillList = [{SId, 1} || SId <- PassiveSkill],
	% SkillExtraAttr = lib_skill_attr:count_skill_attr_with_mod_id(?MOD_CHILD, ActiveSkill, RoleLv),
	SkillExtraAttr = lib_skill_attr:count_skill_attr_with_mod_id(?MOD_CHILD, PassiveSkillList++SkillList, 1),
	util:combine_list(SkillAttr ++ SkillExtraAttr).

%% 计算载具属性
calc_vehicle_attr(VehicleList) ->
	F = fun({VehicleId, Stage}, TAttrList) ->
		case data_child:get_child_vehicle_cfg(VehicleId, Stage) of
			#child_vehicle_cfg{add_attr = AddAttr} ->
				util:combine_list(AddAttr ++ TAttrList);
			_ -> TAttrList
		end
	    end,
	lists:foldl(F, [], VehicleList).

%% 计算玩具属性(只算装备的)
%%calc_toy_attr(ToyList) ->
%%	F = fun({_SlotId, GoodId}, TAttrList) ->
%%		case lib_goods_api:get_goods_info(GoodId, ?GOODS_LOC_CHILD_TOY_SLOT) of
%%			#goods{goods_id = GoodTypeId, extra_data = ExtraData} ->
%%				Lv =
%%				case ExtraData of
%%					[{?GOODS_OTHER_KEY_CHILD_TOY_LV, TLv}] -> TLv;
%%					_ -> 0
%%				end,
%%				case data_child:get_child_toy_cfg(GoodTypeId) of
%%					#child_toy_cfg{toy_color = Color, toy_type = Type, attr_list = AttrList} ->
%%						case data_child:get_toy_stren_cfg(Type, Color, Lv) of
%%							#child_toy_stren_cfg{add_attr = AddAttr} ->
%%								util:combine_list(AttrList ++ AddAttr ++ TAttrList);
%%							_ ->
%%								util:combine_list(AttrList ++ TAttrList)
%%						end;
%%					_ -> TAttrList
%%				end;
%%			_ -> TAttrList
%%		end
%%	end,
%%	lists:foldl(F, [], ToyList).

%% 计算玩具属性(新)
calc_toy_attr_new(ToySuit, BoxLv) ->
	SuitList = maps:to_list(ToySuit),
	ToyAttr = lists:foldl(
		fun({_SuitType, #toy_suit{toy_list = ToyList}}, TAttr) ->
				F = fun(ToyId, TAttr1) ->
					case data_child:get_child_toy_new_cfg(ToyId) of
						#child_toy_new_cfg{attr_list = AttrList} ->
							util:combine_list(TAttr1 ++ AttrList);
						_ ->
							TAttr1
					end
				end,
				lists:foldl(F, TAttr, ToyList);
			(_, TAttr) ->
				TAttr
	end, [], SuitList),
	case data_child:get_child_toy_box_upgrade_cfg(BoxLv) of
		#child_toy_box_upgrade_cfg{add_attr = BoxAttr} ->
			ToyAttr ++ BoxAttr;
		_ ->
			ToyAttr
	end.

%% 计算时装属性
calc_fashion_attr(FashionList) ->
	F = fun({FashionId, Lv}, TAttrList) ->
		case data_child:get_child_fashion_cfg(FashionId, Lv) of
			#child_fashion_cfg{attr_list = AttrList} ->
				util:combine_list(AttrList ++ TAttrList);
			_ ->
				TAttrList
		end
	end,
	lists:foldl(F, [], FashionList).

%% 计算属性
calc_child_attr(StatusChild) ->
	#status_child{
		child_sex        = ChildSex,
		child_age_year   = AgeYear,
		child_age_month  = AgeMonth,
		active_skill     = ActiveSkill,
		passive_skill    = PassiveSkill,
		vehicle          = VehicleList,
		% toy_list         = ToyList,
		toy_suit         = ToySuit,
		box_lv           = BoxLv,
		fashion_list     = FashionList
	} = StatusChild,
	%% 培养属性
	AgeAttr =
	case data_child:get_child_grow_up_cfg(AgeYear, AgeMonth) of
		#child_grow_up_cfg{
			attr_list = TAgeAttr
		} -> TAgeAttr;
		_ ->  []
	end,
	%% 载具属性
	VehicleAttr = calc_vehicle_attr(VehicleList),
	%% 技能属性
	SkillAttr = calc_skill_attr(ActiveSkill, PassiveSkill),
	%% 玩具属性
	ToyAttr = calc_toy_attr_new(ToySuit, BoxLv),
	%% 时装属性
	FashionAttr = calc_fashion_attr(FashionList),
	%% 领养了孩子才计算初始战力
	case ChildSex > 0 of
		true ->
			util:combine_list(AgeAttr ++ VehicleAttr ++ SkillAttr ++ ToyAttr ++ FashionAttr);
		_ ->
			[]
	end.

%% 刷新属性战力
refresh_attr(#player_status{status_child = StatusChild} = Player, Type) ->
	AttrList   = calc_child_attr(StatusChild),
	ChildPower = calc_child_power(AttrList),
	SkillList = StatusChild#status_child.active_skill ++ [{SkillId, 1}||SkillId <- StatusChild#status_child.passive_skill],
	SkillPower = lib_skill:count_skill_power(SkillList),
	NewStatusChild = StatusChild#status_child{
		attr_list   = AttrList,
		child_power = ChildPower,
		extra_power = SkillPower
	},
	NewPlayer = lib_child_util:save_dict_status_child(NewStatusChild, Player),
	RefreshPlayer = lib_player:count_player_attribute(NewPlayer, ?MOD_CHILD, Type),
	BattleAttr = lib_child_api:get_child_battle_attr(RefreshPlayer),
	mod_scene_agent:update(RefreshPlayer, [{child_battle_attr, BattleAttr}]),
	lib_common_rank_api:refresh_rank_by_child(RefreshPlayer),
	lib_player:send_attribute_change_notify(RefreshPlayer, ?NOTIFY_ATTR),
	RefreshPlayer.

%% -----------------------------------------------
make_list(child, ChildInfo) ->
	[ChildName, ChildSex, ChildAgeYear, ChildAgeMonth, ChildAgeExp,
		HeartLinkExp, HeartLinkRewardStr, VoteTimes, ShowOffTimes, RefreshTime, LastShowOffTime,
		IsFollow, ShowVehicle, BoxLv, AdoptTime] = ChildInfo,
	StatusChild =
	#status_child{
		child_name = ChildName,
		child_sex = ChildSex,
		child_age_year = ChildAgeYear,
		child_age_month = ChildAgeMonth,
		child_age_exp = ChildAgeExp,
		heart_link_exp = HeartLinkExp,
		heart_reward = util:bitstring_to_term(HeartLinkRewardStr),
		vote_times = VoteTimes,
		show_off_times = ShowOffTimes,
		refresh_time = RefreshTime,
		last_show_off_time = LastShowOffTime,
		is_follow = IsFollow,
		show_vehicle = ShowVehicle,
		box_lv = BoxLv,
		adopt_time = AdoptTime
	},
	StatusChild;
make_list(child_daily_task, DailyTaskInfos) ->
	F = fun(TaskInfo, TDailyTaskList) ->
		[Sequence, DetailIdList, Progress, TaskState] = TaskInfo,
		DailyTask = #child_daily_task{
			sequence   = Sequence,
			detail_id  = util:bitstring_to_term(DetailIdList),
			progress   = Progress,
			task_state = TaskState
		},
		lists:keystore(Sequence, #child_daily_task.sequence, TDailyTaskList, DailyTask)
	end,
	lists:foldl(F, [], DailyTaskInfos);
make_list(child_vote_log, VoteLogInfos) ->
	F = fun(VoteLogInfo, TBeVotedLogList) ->
		[VoteId, VoteName, VoteTime, FeedBackStatus] = VoteLogInfo,
		VoteLog = #child_vote_log{
			vote_id          = VoteId,
			vote_name        = VoteName,
			time             = VoteTime,
			feed_back_status = FeedBackStatus
		},
		lists:keystore(VoteId, #child_vote_log.vote_id, TBeVotedLogList, VoteLog)
	end,
	lists:foldl(F, [], VoteLogInfos).

%% 发送消息
send_msg(Sid, Cmd, Msg) ->
	{ok, Bin} = pt_165:write(Cmd, Msg),
	lib_server_send:send_to_sid(Sid, Bin).

%% 发送错误信息
send_error(Sid, ErrCode) ->
	{ok, Bin} = pt_165:write(16500, [ErrCode]),
	lib_server_send:send_to_sid(Sid, Bin).

%% 名字字符串检查错误码转换
change_error_code(ErrCode) ->
	case ErrCode of
		invalid_utf8 -> ?ERRCODE(illegal_character);
		width -> ?ERRCODE(not_enough_length);
		keyword -> ?ERRCODE(err165_exits_word_sensitive);
		_ -> ?FAIL
	end.

%%获取同心值
get_player_link_heart(Player)->
	#player_status{status_child = StatusChild} = Player,
	case StatusChild#status_child.child_sex > 0 of
		true ->
			StatusChild#status_child.heart_link_exp;
		_->
			0
	end.

%% ---------------------------------------------------------------------------------
%% @doc 新增领取奖励 @end
%% data: 2021-07-02
%% 领取分享/昨日榜奖励
receive_share_reward(Player) ->
	#player_status{sid = Sid, id = RoleId, status_child = StatusChild} = Player,
	#status_child{show_off_times = ShowOffTimes, share_reward = ShareReward
		,yest_rank = YestRank, yest_reward = YestReward
	} = StatusChild,
	if
		ShowOffTimes =< 0 ->
			send_msg(Sid, 16540, [?ERRCODE(err165_has_not_show_off), 1]),
			{ok, Player};
		ShareReward > 0 ->
			send_msg(Sid, 16540, [?ERRCODE(err165_has_received_reward), 1]),
			{ok, Player};
		true ->
			case data_child:get_child_kv_cfg(show_gift) of
				#child_constant_cfg{constant = [_|_] = Reward} -> ok;
				_ -> Reward = []
			end,
			case Reward =/= [] of
				true ->
					Produce = #produce{type = child_share_reward, reward = Reward},
					{ok, Player1} = lib_goods_api:send_reward_with_mail(Player, Produce),
					NewStatusChild = StatusChild#status_child{share_reward = 1},
					lib_child_util:save_db_child_reward(RoleId, 1, YestRank, YestReward),
					NewPlayer = Player1#player_status{status_child = NewStatusChild},
					send_msg(Sid, 16540, [?SUCCESS, 1]),
					{ok, NewPlayer};
				_ ->
					send_msg(Sid, 16540, [?ERRCODE(err165_reward_cfg_err), 1]),
					{ok, Player}
			end
	end.

receive_yest_reward(Player) ->
	#player_status{sid = Sid, id= RoleId, status_child = StatusChild} = Player,
	#status_child{yest_rank = YestRank, yest_reward = YestReward, share_reward = ShareReward} = StatusChild,
	if
		YestReward > 0 ->
			send_msg(Sid, 16540, [?ERRCODE(err165_has_received_reward), 2]),
			{ok, Player};
		true ->
			case data_child:get_child_vote_reward_cfg(YestRank) of
				#child_vote_reward_cfg{reward_list = [_|_] = Reward} -> ok;
				_ -> Reward = []
			end,
			case Reward =/= [] of
				true ->
					Produce = #produce{type = child_rank_reward, reward = Reward},
					{ok, Player1} = lib_goods_api:send_reward_with_mail(Player, Produce),
					NewStatusChild = StatusChild#status_child{yest_reward = 1},
					lib_child_util:save_db_child_reward(RoleId, ShareReward, YestRank, 1),
					NewPlayer = Player1#player_status{status_child = NewStatusChild},
					send_msg(Sid, 16540, [?SUCCESS, 2]),
					{ok, NewPlayer};
				_ ->
					send_msg(Sid, 16540, [?ERRCODE(err165_rank_has_not_reward), 2]),
					{ok, Player}
			end
	end.

%% ------------------------ gm操作 --------------------------
gm_change_link_heart_exp(Player, Exp) ->
	#player_status{id = RoleId, sid = Sid, status_child = StatusChild} = Player,
	NewStatusChild = do_upgrade_link_heart(StatusChild, Exp),
	#status_child{
		heart_link_exp   = NewHeartLinkExp
	} = NewStatusChild,
	lib_child_util:update_db_child_link_heart(RoleId, NewHeartLinkExp),
	Player1   = lib_child_util:save_dict_status_child(NewStatusChild, Player),
	lib_task_api:child_heart(Player1,NewHeartLinkExp),
	% NewPlayer = refresh_attr(Player1, upgrade_link_heart),
	send_msg(Sid, 16506, [NewHeartLinkExp]),
	{ok, Player1}.
