diff --git a/src/character.cpp b/src/character.cpp index a829eef142034..cabe1c9425578 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -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; diff --git a/src/map.cpp b/src/map.cpp old mode 100644 new mode 100755 index 4e318104fa85d..91993dc078374 --- a/src/map.cpp +++ b/src/map.cpp @@ -4106,7 +4106,8 @@ item &map::add_item_or_charges( const tripoint &pos, item obj, bool overflow ) std::vector 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; @@ -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; } } diff --git a/src/monattack.cpp b/src/monattack.cpp index afae063fb7ae7..0e52da8abb402 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -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." ) ); diff --git a/src/monstergenerator.cpp b/src/monstergenerator.cpp index 7fc39dfbb71ab..810c5750ec77a 100644 --- a/src/monstergenerator.cpp +++ b/src/monstergenerator.cpp @@ -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 + diff --git a/src/npc.cpp b/src/npc.cpp index 5a88fafd1c40e..c0ec9b68fda0d 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -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; } diff --git a/src/pathfinding.cpp b/src/pathfinding.cpp index 1a7691155d728..2857b3f6efff8 100644 --- a/src/pathfinding.cpp +++ b/src/pathfinding.cpp @@ -197,7 +197,7 @@ std::vector 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 ); @@ -224,6 +224,7 @@ std::vector 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; @@ -416,6 +417,11 @@ std::vector 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 diff --git a/src/pathfinding.h b/src/pathfinding.h old mode 100644 new mode 100755 index b66c1bc29b28d..a54b56cbd0b00 --- a/src/pathfinding.h +++ b/src/pathfinding.h @@ -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 @@ -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 ) @@ -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 ) : 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