Skip to content

Commit

Permalink
Merge pull request CleverRaven#19 from Coolthulhu/pathfinding-climb
Browse files Browse the repository at this point in the history
Make NPCs pathfind over (and not just around) fences
  • Loading branch information
Coolthulhu authored Sep 29, 2017
2 parents 93dd9e7 + 421df4d commit 9fc16ac
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ Character::Character() : Creature(), visitable<Character>()

name = "";

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

field_id Character::bloodType() const
Expand Down
3 changes: 3 additions & 0 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8234,6 +8234,9 @@ void map::update_pathfinding_cache( int zlev ) const
cur_value |= PF_SLOW;
} else if( cost <= 0 ) {
cur_value |= PF_WALL;
if( terrain.has_flag( TFLAG_CLIMBABLE ) ) {
cur_value |= PF_CLIMBABLE;
}
}

if( veh != nullptr ) {
Expand Down
2 changes: 1 addition & 1 deletion src/monattack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1373,7 +1373,7 @@ bool mattack::triffid_heartbeat(monster *z)
return true;
}

static pathfinding_settings root_pathfind( 10, 20, 50, false, false, false );
static pathfinding_settings root_pathfind( 10, 20, 50, 0, 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
4 changes: 4 additions & 0 deletions src/monstergenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ void MonsterGenerator::finalize_pathfinding_settings( mtype &mon )
if( mon.path_settings.bash_strength < 0 ) {
mon.path_settings.bash_strength = mon.bash_skill;
}

if( mon.has_flag( MF_CLIMBS ) ) {
mon.path_settings.climb_cost = 3;
}
}

template <typename T>
Expand Down
16 changes: 12 additions & 4 deletions src/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ npc::npc()
companion_mission_time = 0;
last_updated = calendar::turn;

path_settings = pathfinding_settings( 0, 1000, 1000, true, true, true );
path_settings = pathfinding_settings( 0, 1000, 1000, 10, true, true, true );
}

standard_npc::standard_npc( const std::string &name, const std::vector<itype_id> &clothing,
Expand Down Expand Up @@ -2351,14 +2351,22 @@ bool npc::will_accept_from_player( const item &it ) const

const pathfinding_settings &npc::get_pathfinding_settings() const
{
path_settings.bash_strength = smash_ability();

return path_settings;
return get_pathfinding_settings( false );
}

const pathfinding_settings &npc::get_pathfinding_settings( bool no_bashing ) const
{
path_settings.bash_strength = no_bashing ? 0 : smash_ability();
// @todo Extract climb skill
const int climb = std::min( 20, get_dex() );
if( climb > 1 ) {
// Success is !one_in(dex), so 0%, 50%, 66%, 75%...
// Penalty for failure chance is 1/success = 1/(1-failure) = 1/(1-(1/dex)) = dex/(dex-1)
path_settings.climb_cost = ( 10 - climb / 5 ) * climb / ( climb - 1 );
} else {
// Climbing at this dexterity will always fail
path_settings.climb_cost = 0;
}

return path_settings;
}
Expand Down
6 changes: 3 additions & 3 deletions src/npcmove.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1523,17 +1523,17 @@ void npc::move_to( const tripoint &pt, bool no_bashing )
moved = true;
} else if( g->m.open_door( p, !g->m.is_outside( pos() ) ) ) {
moves -= 100;
} else if( g->m.has_flag_ter_or_furn( "CLIMBABLE", p ) ) {
} else if( get_dex() > 1 && g->m.has_flag_ter_or_furn( "CLIMBABLE", p ) ) {
///\EFFECT_DEX_NPC increases chance to climb CLIMBABLE furniture or terrain
int climb = dex_cur;
int climb = get_dex();
if( one_in( climb ) ) {
add_msg_if_npc( m_neutral, _( "%1$s falls tries to climb the %2$s but slips." ),
name.c_str(), g->m.tername(p).c_str() );
moves -= 400;
} else {
add_msg_if_npc( m_neutral, _( "%1$s climbs over the %2$s." ), name.c_str(),
g->m.tername( p ).c_str() );
moves -= (500 - (rng(0,climb) * 20));
moves -= 500 - climb * 10;
moved = true;
}
} else if( !no_bashing && smash_ability() > 0 && g->m.is_bashable( p ) &&
Expand Down
11 changes: 7 additions & 4 deletions src/pathfinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ std::vector<tripoint> map::route( const tripoint &f, const tripoint &t,

int max_length = settings.max_length;
int bash = settings.bash_strength;
int climb_cost = settings.climb_cost;
bool doors = settings.allow_open_doors;
bool trapavoid = settings.avoid_traps;

Expand Down Expand Up @@ -307,17 +308,19 @@ std::vector<tripoint> map::route( const tripoint &f, const tripoint &t,
const int rating = ( bash == 0 || cost != 0 ) ? -1 :
bash_rating_internal( bash, furniture, terrain, false, veh, part );

if( cost == 0 && rating <= 0 && ( !doors || !terrain.open ) && veh == nullptr ) {
if( cost == 0 && rating <= 0 && ( !doors || !terrain.open ) && veh == nullptr && climb_cost <= 0 ) {
layer.state[index] = ASL_CLOSED; // Close it so that next time we won't try to calc costs
continue;
}

newg += cost;
if( cost == 0 ) {
// Handle all kinds of doors
// Only try to open INSIDE doors from the inside
if( doors && terrain.open &&
if( climb_cost > 0 && p_special & PF_CLIMBABLE ) {
// Climbing fences
newg += climb_cost;
} else if( doors && terrain.open &&
( !terrain.has_flag( "OPENCLOSE_INSIDE" ) || !is_outside( cur ) ) ) {
// Only try to open INSIDE doors from the inside
// To open and then move onto the tile
newg += 4;
} else if( veh != nullptr ) {
Expand Down
11 changes: 8 additions & 3 deletions src/pathfinding.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ enum pf_special : char {
PF_FIELD = 0x08, // Dangerous field
PF_TRAP = 0x10, // Dangerous trap
PF_UPDOWN = 0x20, // Stairs, ramp etc.
PF_CLIMBABLE = 0x40, // 0 move cost but can be climbed on examine
};

constexpr pf_special operator | ( pf_special lhs, pf_special rhs )
Expand Down Expand Up @@ -53,16 +54,20 @@ struct pathfinding_settings {
// At least 2 times the above, usually more
int max_length = 0;

// Expected terrain cost (2 is flat ground) of climbing a wire fence
// 0 means no climbing
int climb_cost = 0;

bool allow_open_doors = false;
bool avoid_traps = false;

bool allow_climb_stairs = true;

pathfinding_settings() = default;
pathfinding_settings( const pathfinding_settings & ) = default;
pathfinding_settings( int bs, int md, int ml, bool aod, bool at, bool acs )
: bash_strength( bs ), max_dist( md ), max_length( ml ), allow_open_doors( aod ),
avoid_traps( at ), allow_climb_stairs( acs ) {}
pathfinding_settings( int bs, int md, int ml, int cc, bool aod, bool at, bool acs )
: bash_strength( bs ), max_dist( md ), max_length( ml ), climb_cost( cc ),
allow_open_doors( aod ), avoid_traps( at ), allow_climb_stairs( acs ) {}
};

#endif

0 comments on commit 9fc16ac

Please sign in to comment.