bool vehicle::turrets_aim() { // reload all turrets and clear any existing targets auto opts = turrets(); for( auto e : opts ) { turret_reload( *e ); e->target.first = tripoint_min; e->target.second = tripoint_min; } // find radius of a circle centered at u encompassing all points turrets can aim at int range = std::accumulate( opts.begin(), opts.end(), 0, [&]( const int lhs, const vehicle_part * e ) { if( turret_query( *e ) != turret_status::ready ) { return lhs; } tripoint pos = global_part_pos3( *e ); const int rng = e->base.gun_range(); int res = 0; res = std::max( res, rl_dist( g->u.pos(), { pos.x + rng, pos.y, pos.z } ) ); res = std::max( res, rl_dist( g->u.pos(), { pos.x - rng, pos.y, pos.z } ) ); res = std::max( res, rl_dist( g->u.pos(), { pos.x, pos.y + rng, pos.z } ) ); res = std::max( res, rl_dist( g->u.pos(), { pos.x, pos.y - rng, pos.z } ) ); return std::max( lhs, res ); } ); // fake gun item to aim item pointer( "vehicle_pointer" ); pointer.set_curammo( "pointer_fake_ammo" ); pointer.ammo_data()->ammo->range = range; tripoint pos = g->u.pos(); std::vector<tripoint> trajectory; if( opts.empty() ) { add_msg( m_warning, _( "Can't aim turrets: all turrets are offline" ) ); } else { trajectory = g->pl_target_ui( pos, range, &pointer, TARGET_MODE_TURRET ); g->draw_ter(); } if( !trajectory.empty() ) { // set target for any turrets in range for( auto e : turrets( trajectory.back() ) ) { e->target.second = trajectory.back(); } ///\EFFECT_INT speeds up aiming of vehicle turrets g->u.moves = std::min( 0, g->u.moves - 100 + ( 5 * g->u.int_cur ) ); } for( auto e : opts ) { turret_unload( *e ); } return !trajectory.empty(); }
bool vehicle::turrets_aim() { // reload all turrets and clear any existing targets auto opts = turrets(); for( auto e : opts ) { e->target.first = tripoint_min; e->target.second = tripoint_min; } // find radius of a circle centered at u encompassing all points turrets can aim at int range = std::accumulate( opts.begin(), opts.end(), 0, [&]( const int lhs, vehicle_part * e ) { const auto gun = turret_query( *e ); if( gun.query() != turret_data::status::ready ) { return lhs; } tripoint pos = global_part_pos3( *e ); const int rng = gun.range(); int res = 0; res = std::max( res, rl_dist( g->u.pos(), { pos.x + rng, pos.y, pos.z } ) ); res = std::max( res, rl_dist( g->u.pos(), { pos.x - rng, pos.y, pos.z } ) ); res = std::max( res, rl_dist( g->u.pos(), { pos.x, pos.y + rng, pos.z } ) ); res = std::max( res, rl_dist( g->u.pos(), { pos.x, pos.y - rng, pos.z } ) ); return std::max( lhs, res ); } ); if( opts.empty() ) { add_msg( m_warning, _( "Can't aim turrets: all turrets are offline" ) ); return false; } tripoint pos = g->u.pos(); std::vector<tripoint> trajectory = g->pl_target_ui( TARGET_MODE_TURRET, nullptr, range ); if( !trajectory.empty() ) { // set target for any turrets in range for( auto e : turrets( trajectory.back() ) ) { e->target.second = trajectory.back(); } ///\EFFECT_INT speeds up aiming of vehicle turrets g->u.moves = std::min( 0, g->u.moves - 100 + ( 5 * g->u.int_cur ) ); } return !trajectory.empty(); }
std::vector<vehicle_part *> vehicle::turrets( const tripoint &target ) { std::vector<vehicle_part *> res = turrets(); // exclude turrets not ready to fire or where target is out of range res.erase( std::remove_if( res.begin(), res.end(), [&]( const vehicle_part * e ) { return turret_query( *e ).query() != turret_data::status::ready || rl_dist( global_part_pos3( *e ), target ) > e->base.gun_range(); } ), res.end() ); return res; }