Skip to content

Commit

Permalink
Refactor moving vehicle picking into map.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
irwiss committed Apr 6, 2023
1 parent 1be0151 commit de59c09
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 55 deletions.
35 changes: 35 additions & 0 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,41 @@ bool map::deregister_vehicle_zone( zone_data &zone ) const
return false;
}

std::set<tripoint_bub_ms> map::get_moving_vehicle_targets( const Creature &z, int max_range )
{
const tripoint_bub_ms zpos( z.pos() );
std::set<tripoint_bub_ms> priority;
std::set<tripoint_bub_ms> visible;
for( wrapped_vehicle &v : get_vehicles() ) {
if( !v.v->is_moving() ) {
continue;
}
if( !fov_3d && v.pos.z != zpos.z() ) {
continue;
}
if( rl_dist( zpos, tripoint_bub_ms( v.pos ) ) > max_range + 40 ) {
continue; // coarse distance filter, 40 = ~24 * sqrt(2) - rough max diameter of a vehicle
}
for( const vpart_reference &vpr : v.v->get_all_parts() ) {
const tripoint_bub_ms vppos = static_cast<tripoint_bub_ms>( vpr.pos() );
if( rl_dist( zpos, vppos ) > max_range ) {
continue;
}
if( !z.sees( vppos ) ) {
continue;
}
if( vpr.has_feature( VPFLAG_CONTROLS ) ||
vpr.has_feature( VPFLAG_ENGINE ) ||
vpr.has_feature( VPFLAG_WHEEL ) ) {
priority.emplace( vppos );
} else {
visible.emplace( vppos );
}
}
}
return !priority.empty() ? priority : visible;
}

// 3D vehicle functions

VehicleList map::get_vehicles( const tripoint &start, const tripoint &end )
Expand Down
4 changes: 4 additions & 0 deletions src/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,10 @@ class map
std::vector<zone_data *> get_vehicle_zones( int zlev );
void register_vehicle_zone( vehicle *, int zlev );
bool deregister_vehicle_zone( zone_data &zone ) const;
// returns a list of tripoints which contain parts from moving vehicles within \p max_range
// distance from \p source position, if any parts are CONTROLS, ENGINE or WHEELS returns a
// list of tripoints with exclusively such parts instead. Used for monster gun actor targeting.
std::set<tripoint_bub_ms> get_moving_vehicle_targets( const Creature &source, int max_range );

// Removes vehicle from map and returns it in unique_ptr
std::unique_ptr<vehicle> detach_vehicle( vehicle *veh );
Expand Down
62 changes: 7 additions & 55 deletions src/mattack_actors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@
#include "rng.h"
#include "sounds.h"
#include "translations.h"
#include "vehicle.h"
#include "viewer.h"
#include "veh_type.h"


static const efftype_id effect_badpoison( "badpoison" );
Expand Down Expand Up @@ -833,27 +831,6 @@ int gun_actor::get_max_range() const
return max_range;
}

static vehicle *find_target_vehicle( monster &z, int range )
{
map &here = get_map();
vehicle *chosen = nullptr;
for( wrapped_vehicle &v : here.get_vehicles() ) {
if( !z.sees( v.pos ) ) {
continue;
}
if( !fov_3d && v.pos.z != z.pos().z ) {
continue;
}
int new_dist = rl_dist( z.pos(), v.pos );
if( v.v->velocity != 0 && new_dist < range ) {
chosen = v.v;
range = new_dist;
}
}
return chosen;
}


bool gun_actor::call( monster &z ) const
{
Creature *target;
Expand All @@ -878,47 +855,22 @@ bool gun_actor::call( monster &z ) const
aim_at = target->pos();
} else {
target = z.attack_target();
aim_at = target ? target->pos() : tripoint_zero;
if( !target || !z.sees( *target ) || ( !target->is_monster() && !z.aggro_character ) ) {
//return false;
if( !target_moving_vehicles ) {
return false;
}
//No living targets, try to find a moving car
untargeted = true;
vehicle *veh = find_target_vehicle( z, get_max_range() );
if( !veh ) {
return false;
}
std::vector<tripoint> valid_targets;
std::vector<tripoint> visible_points;
for( const tripoint &p : veh->get_points() ) {
if( !z.sees( p ) ) {
continue;
}
visible_points.push_back( p );
for( const vpart_reference &vp : veh->get_all_parts() ) {
if( vp.pos() != p ) {
continue;
}
if( veh->part_with_feature( vp.part_index(), VPFLAG_CONTROLS, true ) >= 0 &&
veh->part_with_feature( vp.part_index(), VPFLAG_ENGINE, true ) >= 0 &&
veh->part_with_feature( vp.part_index(), VPFLAG_WHEEL, true ) >= 0 ) {
valid_targets.push_back( p );
break;
}
}
}
if( !valid_targets.empty() ) {
aim_at = random_entry( valid_targets, tripoint_zero );
} else if( !visible_points.empty() ) {
aim_at = random_entry( visible_points, tripoint_zero );
} else {
untargeted = true; // no living targets, try to find moving car parts
const std::set<tripoint_bub_ms> moving_veh_parts = get_map()
.get_moving_vehicle_targets( z, get_max_range() );
if( moving_veh_parts.empty() ) {
return false;
}
aim_at = random_entry( moving_veh_parts, tripoint_bub_ms() ).raw();
}
}

int dist = rl_dist( z.pos(), aim_at );
const int dist = rl_dist( z.pos(), aim_at );
if( target ) {
add_msg_debug( debugmode::DF_MATTACK, "Target %s at range %d", target->disp_name(), dist );
} else {
Expand Down

0 comments on commit de59c09

Please sign in to comment.