function flt_can_attack($planet_src, $planet_dst, $fleet = array(), $mission, $options = false) { global $config, $sn_data, $user, $time_now; if ($user['vacation']) { return ATTACK_OWN_VACATION; } if (empty($fleet) || !is_array($fleet)) { return ATTACK_NO_FLEET; } foreach ($fleet as $ship_id => $ship_count) { if ($ship_count > $planet_src[$sn_data[$ship_id]['name']]) { return ATTACK_NO_SHIPS; } } $speed = $options['speed']; if ($speed && ($speed != intval($speed) || $speed < 1 || $speed > 10)) { return ATTACK_WRONG_SPEED; } $speed_factor = get_fleet_speed(); $distance = GetTargetDistance($planet_src['galaxy'], $planet_dst['galaxy'], $planet_src['system'], $planet_dst['system'], $planet_src['planet'], $planet_dst['planet']); $fleet_speed = min(GetFleetMaxSpeed($fleet, 0, $user)); $fleet_speed_percent = $options['fleet_speed_percent'] ? $options['fleet_speed_percent'] : 10; $duration = GetMissionDuration($fleet_speed_percent, $fleet_speed, $distance, $speed_factor); $consumption = GetFleetConsumption($fleet, $speed_factor, $duration, $distance, $fleet_speed, $user, $fleet_speed_percent); if ($planet_src[$sn_data[RES_DEUTERIUM]['name']] < $fleet[RES_DEUTERIUM] + $consumption) { return ATTACK_NO_FUEL; } $fleet_start_time = $time_now + $duration; $fleet_group = $options['fleet_group']; if ($fleet_group) { if ($mission != MT_AKS) { return ATTACK_WRONG_MISSION; } $acs = doquery("SELECT * FROM {{aks}} WHERE id = '{$fleet_group}' LIMIT 1;", '', true); if (!$acs['id']) { return ATTACK_NO_ACS; } if ($planet_dst['galaxy'] != $acs['galaxy'] || $planet_dst['system'] != $acs['system'] || $planet_dst['planet'] != $acs['planet'] || $planet_dst['planet_type'] != $acs['planet_type']) { return ATTACK_ACS_WRONG_TARGET; } if ($fleet_start_time > $acs['ankunft']) { return ATTACK_ACS_TOO_LATE; } } $flying_fleets = $options['flying_fleets']; if (!$flying_fleets) { $flying_fleets = doquery("SELECT COUNT(fleet_id) AS `flying_fleets` FROM {{fleets}} WHERE `fleet_owner` = '{$user['id']}';", '', true); $flying_fleets = $flying_fleets['flying_fleets']; } if (GetMaxFleets($user) <= $flying_fleets && $mission != MT_MISSILE) { return ATTACK_NO_SLOTS; } // Checking for no planet if (!$planet_dst['id_owner']) { if ($mission == MT_COLONIZE && !$fleet[SHIP_COLONIZER]) { return ATTACK_NO_COLONIZER; } if ($mission == MT_EXPLORE || $mission == MT_COLONIZE) { return ATTACK_ALLOWED; } return ATTACK_NO_TARGET; } if ($mission == MT_RECYCLE) { if ($planet_dst['debris_metal'] + $planet_dst['debris_crystal'] <= 0) { return ATTACK_NO_DEBRIS; } if ($fleet[SHIP_RECYCLER] <= 0) { return ATTACK_NO_RECYCLERS; } return ATTACK_ALLOWED; } // Got planet. Checking if it is ours if ($planet_dst['id_owner'] == $user['id']) { if ($mission == MT_TRANSPORT || $mission == MT_RELOCATE) { return ATTACK_ALLOWED; } return ATTACK_OWN; } // No, planet not ours. Cutting mission that can't be send to not-ours planet if ($mission == MT_RELOCATE || $mission == MT_COLONIZE || $mission == MT_EXPLORE) { return ATTACK_WRONG_MISSION; } $enemy = doquery("SELECT * FROM {{users}} WHERE `id` = '{$planet_dst['id_owner']}' LIMIT 1;", '', true); // We cannot attack or send resource to users in VACATION mode if ($enemy['vacation'] && $target_mission != MT_RECYCLE) { return ATTACK_VACATION; } // Multi IP protection. Here we need a procedure to check proxies if (sys_is_multiaccount($user, $enemy)) { return ATTACK_SAME_IP; } $user_points = doquery("SELECT total_points FROM {{statpoints}} WHERE `stat_type` = '1' AND `stat_code` = '1' AND `id_owner` = '{$user['id']}';", '', true); $user_points = $user_points['total_points']; $enemy_points = doquery("SELECT total_points FROM {{statpoints}} WHERE `stat_type` = '1' AND `stat_code` = '1' AND `id_owner` = '{$enemy['id']}';", '', true); $enemy_points = $enemy_points['total_points']; // Is it transport? If yes - checking for buffing to prevent mega-alliance destroyer if ($mission == MT_TRANSPORT) { if ($user_points >= $enemy_points || $config->allow_buffing) { return ATTACK_ALLOWED; } else { return ATTACK_BUFFING; } } // Only aggresive missions passed to this point. HOLD counts as passive but aggresive // Is it admin with planet protection? if ($planet_dst['id_level'] > $user['authlevel']) { return ATTACK_ADMIN; } // Okay. Now skipping protection checks for inactive longer then 1 week if (!$enemy['onlinetime'] || $enemy['onlinetime'] >= $time_now - 60 * 60 * 24 * 7) { if ($enemy_points <= $config->game_noob_points && $user_points > $config->game_noob_points || $config->game_noob_factor && $user_points > $enemy_points * $config->game_noob_factor) { if ($mission != MT_HOLD) { return ATTACK_NOOB; } if ($mission == MT_HOLD && !($user['ally_id'] && $user['ally_id'] == $enemy['ally_id'] && $config->ally_help_weak)) { return ATTACK_NOOB; } } } // Is it HOLD mission? If yes - there should be ally deposit if ($mission == MT_HOLD) { if ($planet_dst[$sn_data[34]['name']]) { return ATTACK_ALLOWED; } return ATTACK_NO_ALLY_DEPOSIT; } if ($mission == MT_SPY) { if ($fleet[SHIP_SPY] >= 1) { return ATTACK_ALLOWED; } return ATTACK_NO_SPIES; } // Is it MISSILE mission? if ($mission == MT_MISSILE) { if ($planet_src[$sn_data[44]['name']] < $sn_data[503]['require'][44]) { return ATTACK_NO_SILO; } if (!$fleet[503]) { return ATTACK_NO_MISSILE; } $distance = abs($planet_dst['system'] - $planet_src['system']); $mip_range = get_missile_range(); if ($distance > $mip_range || $planet_dst['galaxy'] != $planet_src['galaxy']) { return ATTACK_MISSILE_TOO_FAR; } } if ($mission == MT_DESTROY && $planet_dst['planet_type'] != PT_MOON) { return ATTACK_WRONG_MISSION; } if ($mission == MT_ATTACK || $mission == MT_AKS || $mission == MT_DESTROY) { return flt_bashing_check($user, $enemy, $planet_dst, $mission, $duration, $fleet_group); } return ATTACK_ALLOWED; }
function sn_flt_can_attack($planet_src, $planet_dst, $fleet = array(), $mission, $options = false, &$result) { //TODO: try..catch global $config, $user; if ($user['vacation']) { return $result = ATTACK_OWN_VACATION; } if (empty($fleet) || !is_array($fleet)) { return $result = ATTACK_NO_FLEET; } $sn_groups_mission = sn_get_groups('missions'); if (!isset($sn_groups_mission[$mission])) { return $result = ATTACK_MISSION_ABSENT; } $sn_data_mission = $sn_groups_mission[$mission]; //TODO: Проверка на отстуствие ресурсов в нетранспортных миссиях (Транспорт, Передислокация, Колонизация) //TODO: Проверка на наличие ресурсов при Транспорте // TODO: Проверка на отрицательные ресурсы при транспорте // TODO: Проверка на перегрузку при транспорте // TODO: В ракетных миссиях могут лететь только ракеты // TODO: В неракетных миссиях ракеты должны отсутствовать $ships = 0; $recyclers = 0; $spies = 0; $resources = 0; $ship_ids = sn_get_groups('fleet'); $resource_ids = sn_get_groups('resources_loot'); foreach ($fleet as $ship_id => $ship_count) { $is_ship = in_array($ship_id, $ship_ids); $is_resource = in_array($ship_id, $resource_ids); if (!$is_ship && !$is_resource) { // TODO Спецобработчик для Капитана и модулей // return ATTACK_WRONG_UNIT; } if ($ship_count < 0) { return $result = $is_ship ? ATTACK_SHIP_COUNT_WRONG : ATTACK_RESOURCE_COUNT_WRONG; } if ($ship_count > mrc_get_level($user, $planet_src, $ship_id)) { // TODO ATTACK_NO_MISSILE return $result = $is_ship ? ATTACK_NO_SHIPS : ATTACK_NO_RESOURCES; } if ($is_ship) { $single_ship_data = get_ship_data($ship_id, $user); if ($single_ship_data[P_SPEED] <= 0) { return $result = ATTACK_ZERO_SPEED; } $ships += $ship_count; $recyclers += in_array($ship_id, sn_get_groups('flt_recyclers')) ? $ship_count : 0; $spies += $ship_id == SHIP_SPY ? $ship_count : 0; } elseif ($is_resource) { $resources += $ship_count; } } /* if($ships <= 0) { return ATTACK_NO_FLEET; } */ if (isset($options['resources']) && $options['resources'] > 0 && !(isset($sn_data_mission['transport']) && $sn_data_mission['transport'])) { return $result = ATTACK_RESOURCE_FORBIDDEN; } /* elseif($mission == MT_TRANSPORT) { return ATTACK_TRANSPORT_EMPTY; } */ $speed = $options['fleet_speed_percent']; if ($speed && ($speed != intval($speed) || $speed < 1 || $speed > 10)) { return $result = ATTACK_WRONG_SPEED; } $travel_data = flt_travel_data($user, $planet_src, $planet_dst, $fleet, $options['fleet_speed_percent']); if (mrc_get_level($user, $planet_src, RES_DEUTERIUM) < $fleet[RES_DEUTERIUM] + $travel_data['consumption']) { return $result = ATTACK_NO_FUEL; } if ($travel_data['consumption'] > $travel_data['capacity']) { return $result = ATTACK_TOO_FAR; } if ($travel_data['hold'] < $resources) { return $result = ATTACK_OVERLOADED; } $fleet_start_time = SN_TIME_NOW + $travel_data['duration']; $fleet_group = $options['fleet_group']; if ($fleet_group) { if ($mission != MT_AKS) { return $result = ATTACK_WRONG_MISSION; } $acs = doquery("SELECT * FROM {{aks}} WHERE id = '{$fleet_group}' LIMIT 1;", '', true); if (!$acs['id']) { return $result = ATTACK_NO_ACS; } if ($planet_dst['galaxy'] != $acs['galaxy'] || $planet_dst['system'] != $acs['system'] || $planet_dst['planet'] != $acs['planet'] || $planet_dst['planet_type'] != $acs['planet_type']) { return $result = ATTACK_ACS_WRONG_TARGET; } if ($fleet_start_time > $acs['ankunft']) { return $result = ATTACK_ACS_TOO_LATE; } } $flying_fleets = $options['flying_fleets']; if (!$flying_fleets) { $flying_fleets = doquery("SELECT COUNT(fleet_id) AS `flying_fleets` FROM {{fleets}} WHERE `fleet_owner` = '{$user['id']}';", '', true); $flying_fleets = $flying_fleets['flying_fleets']; } if (GetMaxFleets($user) <= $flying_fleets && $mission != MT_MISSILE) { return $result = ATTACK_NO_SLOTS; } // В одиночку шпионские зонды могут летать только в миссии Шпионаж, Передислокация и Транспорт if ($ships && $spies && $spies == $ships && !($mission == MT_SPY || $mission == MT_RELOCATE || $mission == MT_TRANSPORT)) { return $result = ATTACK_SPIES_LONLY; } // Checking for no planet if (!$planet_dst['id_owner']) { if ($mission == MT_COLONIZE && !$fleet[SHIP_COLONIZER]) { return $result = ATTACK_NO_COLONIZER; } if ($mission == MT_EXPLORE || $mission == MT_COLONIZE) { return $result = ATTACK_ALLOWED; } return $result = ATTACK_NO_TARGET; } if ($mission == MT_RECYCLE) { if ($planet_dst['debris_metal'] + $planet_dst['debris_crystal'] <= 0) { return $result = ATTACK_NO_DEBRIS; } if ($recyclers <= 0) { return $result = ATTACK_NO_RECYCLERS; } return $result = ATTACK_ALLOWED; } // Got planet. Checking if it is ours if ($planet_dst['id_owner'] == $user['id']) { if ($mission == MT_TRANSPORT || $mission == MT_RELOCATE) { return $result = ATTACK_ALLOWED; } return $planet_src['id'] == $planet_dst['id'] ? ATTACK_SAME : ATTACK_OWN; } // No, planet not ours. Cutting mission that can't be send to not-ours planet if ($mission == MT_RELOCATE || $mission == MT_COLONIZE || $mission == MT_EXPLORE) { return $result = ATTACK_WRONG_MISSION; } $enemy = db_user_by_id($planet_dst['id_owner']); // We cannot attack or send resource to users in VACATION mode if ($enemy['vacation'] && $mission != MT_RECYCLE) { return $result = ATTACK_VACATION; } // Multi IP protection // TODO: Here we need a procedure to check proxies if (sys_is_multiaccount($user, $enemy)) { return $result = ATTACK_SAME_IP; } $user_points = $user['total_points']; $enemy_points = $enemy['total_points']; // Is it transport? If yes - checking for buffing to prevent mega-alliance destroyer if ($mission == MT_TRANSPORT) { if ($user_points >= $enemy_points || $config->allow_buffing) { return $result = ATTACK_ALLOWED; } else { return $result = ATTACK_BUFFING; } } // Only aggresive missions passed to this point. HOLD counts as passive but aggresive // Is it admin with planet protection? if ($planet_dst['id_level'] > $user['authlevel']) { return $result = ATTACK_ADMIN; } // Okay. Now skipping protection checks for inactive longer then 1 week if (!$enemy['onlinetime'] || $enemy['onlinetime'] >= SN_TIME_NOW - 60 * 60 * 24 * 7) { if ($enemy_points <= $config->game_noob_points && $user_points > $config->game_noob_points || $config->game_noob_factor && $user_points > $enemy_points * $config->game_noob_factor) { if ($mission != MT_HOLD) { return $result = ATTACK_NOOB; } if ($mission == MT_HOLD && !($user['ally_id'] && $user['ally_id'] == $enemy['ally_id'] && $config->ally_help_weak)) { return $result = ATTACK_NOOB; } } } // Is it HOLD mission? If yes - there should be ally deposit if ($mission == MT_HOLD) { if (mrc_get_level($user, $planet_dst, STRUC_ALLY_DEPOSIT)) { return $result = ATTACK_ALLOWED; } return $result = ATTACK_NO_ALLY_DEPOSIT; } if ($mission == MT_SPY) { return $result = $spies >= 1 ? ATTACK_ALLOWED : ATTACK_NO_SPIES; } // Is it MISSILE mission? if ($mission == MT_MISSILE) { $sn_data_mip = get_unit_param(UNIT_DEF_MISSILE_INTERPLANET); if (mrc_get_level($user, $planet_src, STRUC_SILO) < $sn_data_mip[P_REQUIRE][STRUC_SILO]) { return $result = ATTACK_NO_SILO; } if (!$fleet[UNIT_DEF_MISSILE_INTERPLANET]) { return $result = ATTACK_NO_MISSILE; } $distance = abs($planet_dst['system'] - $planet_src['system']); $mip_range = flt_get_missile_range($user); if ($distance > $mip_range || $planet_dst['galaxy'] != $planet_src['galaxy']) { return $result = ATTACK_MISSILE_TOO_FAR; } if (isset($options['target_structure']) && $options['target_structure'] && !in_array($options['target_structure'], sn_get_groups('defense_active'))) { return $result = ATTACK_WRONG_STRUCTURE; } } if ($mission == MT_DESTROY && $planet_dst['planet_type'] != PT_MOON) { return $result = ATTACK_WRONG_MISSION; } if ($mission == MT_ATTACK || $mission == MT_AKS || $mission == MT_DESTROY) { return $result = flt_bashing_check($user, $enemy, $planet_dst, $mission, $travel_data['duration'], $fleet_group); } return $result = ATTACK_ALLOWED; }