Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support pathfinding avoiding sharp objects (barbed wire etc) #37964

Merged
merged 4 commits into from
Feb 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ Character::Character() :

name.clear();

*path_settings = pathfinding_settings{ 0, 1000, 1000, 0, true, true, true, false };
*path_settings = pathfinding_settings{ 0, 1000, 1000, 0, true, true, true, false, true };

move_mode = CMM_WALK;

Expand Down
7 changes: 6 additions & 1 deletion src/map.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -4106,7 +4106,8 @@ item &map::add_item_or_charges( const tripoint &pos, item obj, bool overflow )
std::vector<tripoint> tiles = closest_tripoints_first( pos, max_dist );
tiles.erase( tiles.begin() ); // we already tried this position
const int max_path_length = 4 * max_dist;
const pathfinding_settings setting( 0, max_dist, max_path_length, 0, false, true, false, false );
const pathfinding_settings setting( 0, max_dist, max_path_length, 0, false, true, false, false,
false );
for( const tripoint &e : tiles ) {
if( !inbounds( e ) ) {
continue;
Expand Down Expand Up @@ -8346,6 +8347,10 @@ void map::update_pathfinding_cache( int zlev ) const
cur_value |= PF_UPDOWN;
}

if( terrain.has_flag( TFLAG_SHARP ) ) {
cur_value |= PF_SHARP;
}

cache.special[p.x][p.y] = cur_value;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/monattack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1479,7 +1479,7 @@ bool mattack::triffid_heartbeat( monster *z )
return true;
}

static pathfinding_settings root_pathfind( 10, 20, 50, 0, false, false, false, false );
static pathfinding_settings root_pathfind( 10, 20, 50, 0, false, false, false, false, false );
if( rl_dist( z->pos(), g->u.pos() ) > 5 &&
!g->m.route( g->u.pos(), z->pos(), root_pathfind ).empty() ) {
add_msg( m_warning, _( "The root walls creak around you." ) );
Expand Down
1 change: 1 addition & 0 deletions src/monstergenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,7 @@ void mtype::load( const JsonObject &jo, const std::string &src )
optional( jop, was_loaded, "allow_open_doors", path_settings.allow_open_doors, false );
optional( jop, was_loaded, "avoid_traps", path_settings.avoid_traps, false );
optional( jop, was_loaded, "allow_climb_stairs", path_settings.allow_climb_stairs, true );
optional( jop, was_loaded, "avoid_sharp", path_settings.avoid_sharp, false );
}
difficulty = ( melee_skill + 1 ) * melee_dice * ( bonus_cut + melee_sides ) * 0.04 +
( sk_dodge + 1 ) * ( 3 + armor_bash + armor_cut ) * 0.04 +
Expand Down
2 changes: 1 addition & 1 deletion src/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ npc::npc()
patience = 0;
attitude = NPCATT_NULL;

*path_settings = pathfinding_settings( 0, 1000, 1000, 10, true, true, true, false );
*path_settings = pathfinding_settings( 0, 1000, 1000, 10, true, true, true, false, true );
for( direction threat_dir : npc_threat_dir ) {
ai_cache.threat_map[ threat_dir ] = 0.0f;
}
Expand Down
8 changes: 7 additions & 1 deletion src/pathfinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ std::vector<tripoint> map::route( const tripoint &f, const tripoint &t,
}
// First, check for a simple straight line on flat ground
// Except when the line contains a pre-closed tile - we need to do regular pathing then
static const auto non_normal = PF_SLOW | PF_WALL | PF_VEHICLE | PF_TRAP;
static const auto non_normal = PF_SLOW | PF_WALL | PF_VEHICLE | PF_TRAP | PF_SHARP;
if( f.z == t.z ) {
const auto line_path = line_to( f, t );
const auto &pf_cache = get_pathfinding_cache_ref( f.z );
Expand All @@ -224,6 +224,7 @@ std::vector<tripoint> map::route( const tripoint &f, const tripoint &t,
bool doors = settings.allow_open_doors;
bool trapavoid = settings.avoid_traps;
bool roughavoid = settings.avoid_rough_terrain;
bool sharpavoid = settings.avoid_sharp;

const int pad = 16; // Should be much bigger - low value makes pathfinders dumb!
int minx = std::min( f.x, t.x ) - pad;
Expand Down Expand Up @@ -416,6 +417,11 @@ std::vector<tripoint> map::route( const tripoint &f, const tripoint &t,
}
}
}

if( sharpavoid && p_special & PF_SHARP ) {
layer.state[index] = ASL_CLOSED; // Avoid sharp things
}

}

// If not visited, add as open
Expand Down
10 changes: 7 additions & 3 deletions src/pathfinding.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include "game_constants.h"

enum pf_special : char {
enum pf_special : int {
PF_NORMAL = 0x00, // Plain boring tile (grass, dirt, floor etc.)
PF_SLOW = 0x01, // Tile with move cost >2
PF_WALL = 0x02, // Unpassable ter/furn/vehicle
Expand All @@ -13,6 +13,7 @@ enum pf_special : char {
PF_TRAP = 0x10, // Dangerous trap
PF_UPDOWN = 0x20, // Stairs, ramp etc.
PF_CLIMBABLE = 0x40, // 0 move cost but can be climbed on examine
PF_SHARP = 0x80, // sharp items (barbed wire, etc)
};

constexpr pf_special operator | ( pf_special lhs, pf_special rhs )
Expand Down Expand Up @@ -60,12 +61,15 @@ struct pathfinding_settings {
bool avoid_traps = false;
bool allow_climb_stairs = true;
bool avoid_rough_terrain = false;
bool avoid_sharp = false;

pathfinding_settings() = default;
pathfinding_settings( const pathfinding_settings & ) = default;
pathfinding_settings( int bs, int md, int ml, int cc, bool aod, bool at, bool acs, bool art )
pathfinding_settings( int bs, int md, int ml, int cc, bool aod, bool at, bool acs, bool art,
bool as )
codemime marked this conversation as resolved.
Show resolved Hide resolved
: bash_strength( bs ), max_dist( md ), max_length( ml ), climb_cost( cc ),
allow_open_doors( aod ), avoid_traps( at ), allow_climb_stairs( acs ), avoid_rough_terrain( art ) {}
allow_open_doors( aod ), avoid_traps( at ), allow_climb_stairs( acs ), avoid_rough_terrain( art ),
avoid_sharp( as ) {}
};

#endif