/** * C++ 杀怪接口 * @param $roles * @param $npc_sid * @param $npc_entity_id */ public function kill_monster($roles, $combo_num, $npc_sid, $npc_entity_id, $roles_attacker_of_resource_fight, $vip_type) { $out = array('roles' => $roles, 'loots' => array(), 'silver' => array(), 'exp' => array(), 'npc_entity_id' => $npc_entity_id, 'mojos' => array()); if (empty($roles) || empty($npc_sid)) { return $out; } if ($vip_type == 1) { $npc = Cache_UnionWantedNpc::getInstance()->get_union_wanted_npc($npc_sid); } else { $npc = Cache_Npc::getInstance()->get_npc_info_from_cache($npc_sid); } $exp_give = $npc['exp_give']; $arr_exp_give = explode("|", $exp_give); $item_id = intval($arr_exp_give[0]); $item_num = intval($arr_exp_give[1]); //挂机副本几人打怪 /* if(Com_Array::is_good_arr($roles_attacker_of_resource_fight)){ $out = $this->roles_attacker_of_resource_fight($out,$roles_attacker_of_resource_fight,$item_num); $out['roles'] = $roles_attacker_of_resource_fight; return $out; }else{ */ if ($roles) { foreach ($roles as $key => $player_id) { $exp_addition = Cache_Combo::getInstance()->get_combo_addition($combo_num[$key]); $drop_reward = array(); //挂机副本不加经验 if ($this->_begin_batch) { if (!isset($this->_player_infos[$player_id])) { $this->_player_infos[$player_id] = $this->get_data('Player')->get_player_info($player_id, array('name', 'map_id', 'level', 'exp', 'level_exp', 'career_type', 'vip', 'after_hero_hole', 'privilege_level')); } if (!isset($this->_player_detail[$player_id])) { $this->_player_detail[$player_id] = $this->get_data('PlayerDetail')->get_player_detail($player_id, array('buff_exp_addition')); } $player_info = $this->_player_infos[$player_id]; $player_detail = $this->_player_detail[$player_id]; } else { $player_info = $this->get_data('Player')->get_player_info($player_id, array('name', 'map_id', 'level', 'exp', 'level_exp', 'career_type', 'vip', 'after_hero_hole', 'privilege_level')); $player_detail = $this->get_data('PlayerDetail')->get_player_detail($player_id, array('buff_exp_addition')); } $map_id = $player_info['map_id']; $map_join_info = Cache_ResourceFight::getInstance()->get_resource_fight($map_id); if ($map_join_info) { /* $playerDailyTimeInfo = $this->get_data("PlayerDailyTime")->get_player_used_time($player_id,array("auto_pve_12hour_left_time")); if(intval($playerDailyTimeInfo["auto_pve_12hour_left_time"])>0){ $common_drop = Cache_ResourceFightPropLoot::getInstance()->get_resource_fight_prop_loot($player_info['level']); $arr_item = array(); if($common_drop > 0){ $item = Cache_PropLoot::getInstance()->get_prop_loot($common_drop,$player_info['career_type']); if($item){ $arr_item = array_merge($arr_item,$item); } } if($arr_item){ foreach($arr_item as $val){ $drop_reward[$val['item_id']] = array('type'=>Cache_FbLoot::getInstance()->get_item_key($val['item_id']),'item_id'=>$val['item_id'],'item_num'=>$val['item_num']); } } Com_Log::write('xgame.auto_pve_data',"npc_sid={$npc_sid}"); $this->get_game('AutoPve')->async_trigger_auto_pve($player_id,$item_num,array(),$drop_reward); } */ $out['loots'][] = array(); $out['silver'][] = 0; $out['exp'][] = 0; $out['mojos'][] = 0; } else { if ($this->_begin_batch) { if (!isset($this->_player_tasks[$player_id])) { $this->_player_tasks[$player_id] = $this->get_data('PlayerTask')->get_task_info($player_id); } $arr_player_task = $this->_player_tasks[$player_id]; } else { $arr_player_task = $this->get_data('PlayerTask')->get_task_info($player_id); } $task_info = reset($arr_player_task['main_val']); $is_update = false; $this->get_game('TaskTrigger')->trigger_task($player_id, 1, $npc_sid, 1, $arr_player_task, $player_info, $this->_begin_batch, $is_update); //杀怪任务 #$this->_player_tasks[$player_id] = $arr_player_task; if ($is_update) { $this->_update_tasks[$player_id] = 1; } if ($player_info['level'] > 20) { #减轻服务器压力,20级之后才有日常任务 $this->get_game('TaskTrigger')->trigger_task($player_id, 116, $npc_sid, 1, $arr_player_task); //杀怪日常任务 } $this->_player_tasks[$player_id] = $arr_player_task; # 必须放在日常任务触发之后,否则日常任务的进度不会更新 $arr_item = array(); #序章的怪物掉落是不是可以特殊处理? if ($npc['common_drop1'] > 0) { $item = Cache_PropLoot::getInstance()->get_prop_loot($npc['common_drop1'], $player_info['career_type']); if ($item) { $arr_item = array_merge($arr_item, $item); } } if ($npc['common_drop2'] > 0) { $item = Cache_PropLoot::getInstance()->get_prop_loot($npc['common_drop2'], $player_info['career_type']); if ($item) { $arr_item = array_merge($arr_item, $item); } } if ($npc['common_drop3'] > 0) { $item = Cache_PropLoot::getInstance()->get_prop_loot($npc['common_drop3'], $player_info['career_type']); if ($item) { $arr_item = array_merge($arr_item, $item); } } if ($npc['common_drop4'] > 0) { $item = Cache_PropLoot::getInstance()->get_prop_loot($npc['common_drop4'], $player_info['career_type']); if ($item) { $arr_item = array_merge($arr_item, $item); } } if ($npc['common_drop5'] > 0) { $item = Cache_PropLoot::getInstance()->get_prop_loot($npc['common_drop5'], $player_info['career_type']); if ($item) { $arr_item = array_merge($arr_item, $item); } } $loots = array(); $reward = array(); # 在序章某人人物下的道具默认进包裹 $silver = 0; $crystal = 0; $add_exp = 0; $type = Cache_FbLoot::getInstance()->get_item_key($item_id); if ($type == 'silver') { $silver += $item_num; //银两 } else { if ($type == 'exp') { $add_exp += $item_num; } elseif ($type == 'prop') { for ($i = 0; $i < $item_num; $i++) { array_push($loots, $item_id); } $reward[] = array('type' => $type, 'item_id' => $item_id, 'item_num' => $item_num); } } if ($arr_item) { foreach ($arr_item as $val) { if ($val['type'] == 'silver') { $silver += $val['item_num']; //银两 } elseif ($val['type'] == 'crystal') { $crystal += $val['item_num']; //魔晶 } elseif ($val['type'] == 'prop') { // Com_Log::write("monster_loot.".$player_id,"item_num:{$val['item_num']}"); for ($i = 0; $i < $val['item_num']; $i++) { array_push($loots, $val['item_id']); } // Com_Log::write("monster_loot.".$player_id,"loot:".var_export($loots,true)); $reward[] = array('type' => $val['type'], 'item_id' => $val['item_id'], 'item_num' => $val['item_num']); } elseif ($val['type'] == 'exp') { $add_exp += $val['item_num']; } } } $out['loots'][] = $loots; $out['silver'][] = $silver; $out['mojos'][] = $crystal; if ($player_info['map_id'] != 2100) { // $add_exp = $add_exp * (1+$exp_addition); } $buff_exp_addition = $player_detail['buff_exp_addition']['exp']; // Com_Log::write("buff_exp_addition.".$player_id,"buff_exp_addition:{$buff_exp_addition}"); // Com_Log::write("buff_exp_addition.".$player_id,"exp:{$add_exp}"); $add_exp += $add_exp * ($buff_exp_addition / 100); #buff药加成 // Com_Log::write("buff_exp_addition.".$player_id,"exp_buff:{$add_exp}"); $out['exp'][] = $add_exp; if ($add_exp > 0) { $this->batch_add_exp($player_id, $player_info, $add_exp); } } } } //} return $out; }
/** * 初始化天梯面板 * 规则:按排序规则取8名玩家天梯信息 * @param $player_id * @return array */ public function get_challenge_list($player_id) { $this->get_game('PlayerFunc')->get_func_is_open($player_id, $this->func_id); $player_info = $this->get_data('Player')->get_player_info($player_id); if (empty($player_info)) { $this->throw_error('20002'); // 没有该玩家信息! } # 获取购买消耗信息 $buy_times_info = Cache_BuyTimes::getInstance()->get_buy_times_info(2, 1); # 获取: 天梯每日已挑战次数 + 每日挑战购买次数 + 当天天梯剩余可用挑战次数 $challenge_battle_num = $this->get_data('PlayerDailyTime')->get_player_used_time($player_id, 'challenge_battle_num'); $challenge_battle_buy_num = $this->get_data('PlayerDailyTime')->get_player_used_time($player_id, 'challenge_battle_buy_num'); if (empty($challenge_battle_num)) { $challenge_battle_num = 0; } if (empty($challenge_battle_buy_num)) { $challenge_battle_buy_num = 0; } $challenge_battle_num_max = $challenge_battle_buy_num * $buy_times_info['per_num'] + $this->challenge_battle_stint; # 获取: 天梯连胜奖励属性加成 + 天梯连败挑战属性加成 $award_add_info = Cache_Ladder::getInstance()->get_award_add_info($player_info['challenge_cont_win']); $ability_add_info = Cache_Ladder::getInstance()->get_ability_add_info($player_info['challenge_cont_lose']); #--------------------------------------------------------------------- # 挑战CD时间,与是否能够挑战判断 #--------------------------------------------------------------------- $cd_acc_lock = $this->get_data('Challenge')->get_cd_acc_lock($player_id); # 获取天梯挑战CD时间累计锁状态 $challenge_remain_cd = $this->get_data('Challenge')->get_challenge_remain_cd($player_id); # 获取:天梯挑战剩余cd时间 $allow_battle = 1; if (!empty($cd_acc_lock)) { # CD时间累计锁打开,不再允许CD累计 if ($challenge_remain_cd > 0) { $allow_battle = 0; } } else { # CD时间累计锁关闭,允许CD累计 if ($challenge_remain_cd >= $this->challenge_battle_cd_stint) { $allow_battle = 0; } } $first_entry = 0; # 获取:本人当前排名信息 $player_rank_info = $this->get_data('Challenge')->get_player_challenge_rank_info($player_id); if (empty($player_rank_info)) { # 新玩家 $player_rank_info = $this->init_challenge_rank_info($player_id); $first_entry = 1; } else { # 旧玩家 # do nothing } # -------------------------------------------------------------------- # 修正玩家排名 # -------------------------------------------------------------------- $this->correct_player_rank_info($player_rank_info); # 获取:天梯前三玩家列表 + 前三玩家其它信息 list($top_three_list, $top_three_player_ids) = $this->get_data('Challenge')->get_player_list_by_rank(array(3, 2, 1)); $top_three_info = $this->get_data('Player')->get_players_info($top_three_player_ids); foreach ($top_three_list as $rank => $rank_info) { if (!empty($rank_info)) { $top_three_list[$rank] = array('player_id' => $rank_info['player_id'], 'rank' => $rank_info['rank'], 'name' => $top_three_info[$rank_info['player_id']]['name'], 'sum_fpower' => intval($top_three_info[$rank_info['player_id']]['sum_fpower'])); $top_three_list[$rank]['avatar'] = $this->get_game('KFArena')->get_player_avatar($rank_info['player_id']); $top_three_list[$rank]['level'] = $top_three_info[$rank_info['player_id']]['level']; } } # 获取天梯对手玩家列表 list($opponent_list, $opponent_player_ids, $hold_monster_info) = $this->get_opponent_list($player_rank_info); #var_export($opponent_list); # 对对手列表添加额外奖励buff信息 $opponent_list = $this->challenge_reward_buff_handle($opponent_list, $player_id, $player_rank_info['challenge_status']); #var_export($opponent_list); # 保存玩家最新的对手列表信息到REDIS,每次玩家进入天梯面板时更新,仅用于挑战对手时做参数验证与取相关信息 $simplified_oppo_list = $this->get_simplified_opponent_list($opponent_list); $this->record_latest_opponent_list($player_id, $simplified_oppo_list); # 获取天梯对手其它信息 $opponent_info = $this->get_data('Player')->get_players_info($opponent_player_ids); # 需要name,level,sum_fpower信息 $monster_info = Cache_Npc::getInstance()->get_npc_info_from_cache($hold_monster_info); foreach ($opponent_list as $sort_weight => $rank_info) { $opponent_list[$sort_weight] = array('player_id' => $rank_info['player_id'], 'rank' => $rank_info['rank'], 'name' => $rank_info['is_mon'] ? $monster_info[$rank_info['player_id']]['name'] : $opponent_info[$rank_info['player_id']]['name'], 'sum_fpower' => $rank_info['is_mon'] ? 0 : intval($opponent_info[$rank_info['player_id']]['sum_fpower']), 'avatar' => array(), 'level' => $rank_info['is_mon'] ? $monster_info[$rank_info['player_id']]['level'] : $opponent_info[$rank_info['player_id']]['level'], 'mon_offset' => $rank_info['mon_offset'], 'mon_rtype' => $rank_info['mon_rtype'], 'reward_buff_type' => $rank_info['reward_buff_rtype'], 'opponent_seq' => $rank_info['opponent_seq']); if ($rank_info['is_mon']) { $opponent_list[$sort_weight]['avatar'] = $this->get_game('KFArena')->get_player_avatar(0, $rank_info['player_id']); # 怪物的战力取其下一个排位玩家的战力,get_opponent_list方法的算法确保了对手列表中,玩家前面第一位一定不会是怪物,即怪物下一位一定可以取到玩家 # 根据sort_weight = mon_offset * 2 - 1;或者sort_weight = rank * 2;算法来看,不可能存在两个怪物是相邻的,即怪物下一位一定是玩家 $opponent_list[$sort_weight]['sum_fpower'] = intval($opponent_info[$opponent_list[$sort_weight + 1]['player_id']]['sum_fpower']); } else { $opponent_list[$sort_weight]['avatar'] = $this->get_game('KFArena')->get_player_avatar($rank_info['player_id']); if (empty($opponent_list[$sort_weight]['avatar'])) { # 脏数据玩家从列表剔除[多重容错] Com_Log::write('xgame.all.error', "Challenge error: unvalid player: " . $rank_info['player_id']); unset($opponent_list[$sort_weight]); } } } # 获取天梯最近战斗记录 $battle_log = $this->get_data('Challenge')->get_player_challenge_log($player_id, $this->challenge_log_stint); $challenge_log = array(); foreach ($battle_log as $log) { $player_info_tmp = $this->get_data('Player')->get_player_info($log['player_id']); if ($log['fight_with_monster']) { $t_player_info = Cache_Npc::getInstance()->get_npc_info_from_cache($log['tgt_player_id']); } else { $t_player_info = $this->get_data('Player')->get_player_info($log['tgt_player_id']); } $c_log['player_name'] = $player_info_tmp['name']; # 发起方名称 $c_log['t_player_name'] = $t_player_info['name']; # 被挑战方名称 if ($log['player_id'] == $player_id) { # 本人是发起方 $c_log['my_result'] = $log['status']; # 0输1赢 if ($log['fight_with_dummy']) { $c_log['my_rank'] = $this->get_display_rank(0, $log['challenge_status_after'], $log['player_fake_rank_after']); $c_log['tgt_player_rank'] = $this->get_display_rank(0, 3, $log['player_fake_rank_before']); } else { $c_log['my_rank'] = $log['player_rank_after']; $c_log['tgt_player_rank'] = $log['tgt_player_rank_before']; } } else { # 本人是被挑战方,此时fight_with_dummy不可能为1 $c_log['my_result'] = $log['status'] ? 0 : 1; # 0输1赢 $c_log['my_rank'] = $log['status'] ? $log['player_rank_before'] : $log['tgt_player_rank_before']; $c_log['tgt_player_rank'] = $log['tgt_player_rank_before']; } $challenge_log[] = $c_log; } # -------------------------------------------------------------------- # 获取全部排名奖励信息,以玩家当前等级为准 # -------------------------------------------------------------------- # 获取vip对奖励的加成信息,只加成非道具奖励 $vip_add_coeff = Com_Util::get_vip_special_reward_add_coeff(10064, $player_info['vip'], $player_info['privilege_level'], $player_id); # 获取排位基础奖励与排位基础奖励加成 $award_rank = Cache_Ladder::getInstance()->get_ladder_award_rank_info($player_info['level']); $whole_award_rank_add = Cache_Ladder::getInstance()->get_whole_ladder_award_rank_add_info(); if (empty($award_rank) || empty($whole_award_rank_add) || empty($award_rank['award_info'])) { $this->throw_error('120104'); # 没有排位奖励配置信息 } $range_rank_reward = array(); # 列表区间各排名对应的奖励[奖励使用通用奖励字符串sid:num|sid:num] foreach ($this->challenge_rank_award_list_range as $range) { foreach ($range as $rank) { # 获取排名对应的加成率 $award_rank_add = array(); foreach ($whole_award_rank_add as $add_info) { if ($rank >= $add_info['rank']) { $award_rank_add = $add_info; break; } } # 计算排名对应的实际排名奖励 /*$coeff = (0 + $award_rank_add['rank_add'] / 10000) * (1 + $vip_add_coeff); $reward_detail = $this->get_game('Reward')->get_reward_detail($award_rank['award_info'], $coeff);*/ $reward_detail = $this->get_game('Reward')->get_reward_detail_other_way($award_rank['award_info'], $award_rank_add['rank_add'], 1); $range_rank_reward[$rank] = $this->get_game('Reward')->get_reward_string_by_reward_detail($reward_detail); # 以通用奖励字符串sid:num|sid:num形式记录 } } $challenge_rank_award_list = array(); foreach ($this->challenge_rank_award_list_range as $range) { $head_rank = $range[0]; $tail_rank = $range[1]; $challenge_rank_award_list[] = array('head_rank' => $head_rank, 'tail_rank' => $tail_rank, 'head_reward' => $range_rank_reward[$head_rank], 'tail_reward' => $range_rank_reward[$tail_rank]); } # -------------------------------------------------------------------- # 获取自身排位奖励配置信息,排位奖励以玩家21点之前最终的排名为准 # -------------------------------------------------------------------- if ($this->current_time >= $this->challenge_reward_time) { # 计算今天排位奖励 $base_rank = $this->get_player_real_base_rank($player_id, $player_info['reg_time'], $player_rank_info); # 今天尚未领取过排位奖励 && 今天21点前有排名[非21点之后进入的新玩家] if ($player_rank_info['latest_reward_time'] < $this->challenge_reward_time && !empty($base_rank)) { $challenge_reward_cd = 0; } else { # 今天领取过奖励 || 今天21点之后进入的新玩家 $challenge_reward_cd = $this->challenge_reward_time + 86400 - $this->current_time > 0 ? $this->challenge_reward_time + 86400 - $this->current_time : 0; } } else { # 优先计算昨天排位奖励,若没有[昨天21点之后才入榜],则计算今天排位奖励 $base_time = $this->challenge_reward_time - 86400; $reward_info = $this->get_data('Challenge')->get_challenge_reward_info($player_id, $base_time); if (empty($reward_info)) { # 昨天奖励未领取过,可能昨天21点前已入榜,也可能尚未入榜 $base_rank = $this->get_player_real_base_rank($player_id, $player_info['reg_time'], $player_rank_info, $base_time); # 获取排位奖励基准排位 if ($base_rank > 0) { # 若昨天21点前已入榜,则CD=0,可领奖 $challenge_reward_cd = 0; } else { # 若昨天21点前尚未入榜,没有排名,则重新换成去今天的排位奖励显示 $challenge_reward_cd = $this->challenge_reward_time - $this->current_time > 0 ? $this->challenge_reward_time - $this->current_time : 0; } } else { # 昨天奖励已经领取,显示今天奖励 $base_rank = 0; $challenge_reward_cd = $this->challenge_reward_time - $this->current_time > 0 ? $this->challenge_reward_time - $this->current_time : 0; } } # 获取排名对应的加成率 $award_rank_add = array(); foreach ($whole_award_rank_add as $add_info) { if ($base_rank >= $add_info['rank']) { $award_rank_add = $add_info; break; } } /*$coeff = (0 + $award_rank_add['rank_add'] / 10000) * (1 + $vip_add_coeff); $reward_detail = $this->get_game('Reward')->get_reward_detail($award_rank['award_info'], $coeff);*/ $reward_detail = $this->get_game('Reward')->get_reward_detail_other_way($award_rank['award_info'], $award_rank_add['rank_add'], 1); $my_rank_reward = $this->get_game('Reward')->get_reward_string_by_reward_detail($reward_detail); # 以通用奖励字符串sid:num|sid:num形式记录 # -------------------------------------------------------------------- # 获取挑战额外加成BUFF可用加成次数 # -------------------------------------------------------------------- $second_last_login_time = !empty($player_info['second_last_login_time']) ? $player_info['second_last_login_time'] : $player_info['login_time']; $extra_buff_avail_num = $this->get_challenge_battle_extra_buff_avail_num($player_id, $second_last_login_time); # -------------------------------------------------------------------- # 天梯剩余挑战次数可购买次数 # -------------------------------------------------------------------- $buy_stint = $this->get_challenge_battle_num_buy_stint($player_id, $buy_times_info); $battle_num_buy_remain = $buy_stint - $challenge_battle_buy_num > 0 ? $buy_stint - $challenge_battle_buy_num : 0; # -------------------------------------------------------------------- # 天梯挑战次数下次购买价格 # -------------------------------------------------------------------- list($cost_currency_type, $cost_currency_value) = $this->get_challenge_next_battle_num_buy_price($player_id, $buy_times_info); $battle_num_next_buy_price = "{$cost_currency_type}:{$cost_currency_value}"; $out = array('challenge_rank' => $player_rank_info['display_rank'], 'challenge_cont_win' => intval($player_info['challenge_cont_win']), 'challenge_cont_lose' => intval($player_info['challenge_cont_lose']), 'challenge_cont_win_award_add' => intval($award_add_info['award_add']), 'challenge_cont_lose_ability_add' => intval($ability_add_info['ability_add']), 'challenge_battle_num' => $challenge_battle_num, 'challenge_battle_stint' => $challenge_battle_num_max, 'challenge_battle_cd' => $challenge_remain_cd, 'honor' => intval($player_info['honor']), 'challenge_reward_cd' => $challenge_reward_cd, 'challenge_rank_reward' => $my_rank_reward, 'challenge_opponent_list' => $opponent_list, 'challenge_battle_log' => $challenge_log, 'challenge_top_three_list' => $top_three_list, 'challenge_rank_award_list' => $challenge_rank_award_list, 'challenge_battle_extra_buff_id' => $this->extra_buff_id_self, 'challenge_battle_extra_buff_avail' => $extra_buff_avail_num, 'challenge_base_rank' => $base_rank, 'battle_num_buy_remain' => $battle_num_buy_remain, 'battle_num_next_buy_price' => $battle_num_next_buy_price, 'first_entry' => $first_entry, 'allow_battle' => $allow_battle); #var_export($out); return $out; }