Skip to content

Commit

Permalink
Replace the old pathfinding_settings with two new classes
Browse files Browse the repository at this point in the history
PathfindingSettings is the direct replacement for the old struct. It
stores how the creature will react to a given terrain, and what actions
they can take.

RealityBubblePathfindingSettings contains settings that govern z-level
movement and parameters related to pathfinding, such as the maximum path
cost.

Currently the extra features of these two classes are completely unused,
as they are intended for integration with the new pathfinder.

Co-authored-by: prharvey <[email protected]>
  • Loading branch information
CLIDragon and prharvey committed Nov 14, 2024
1 parent 60cf27e commit 0a9b8e8
Show file tree
Hide file tree
Showing 18 changed files with 499 additions and 108 deletions.
2 changes: 1 addition & 1 deletion src/avatar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ void avatar::grab( object_type grab_type_new, const tripoint_rel_ms &grab_point_
// eliminate ghost vehicles/furnitures/etc.
update_memory( grab_type, grab_point, /* erase = */ true );

path_settings->avoid_rough_terrain = grab_type != object_type::NONE;
path_settings->set_avoid_rough_terrain( grab_type != object_type::NONE );
}

object_type avatar::get_grab_type() const
Expand Down
11 changes: 9 additions & 2 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,14 @@ Character::Character() :
name.clear();
custom_profession.clear();

*path_settings = pathfinding_settings{ 0, 1000, 1000, 0, true, true, true, true, false, true, creature_size::medium };
PathfindingSettings pf_settings;
pf_settings.set_avoid_bashing(true);
pf_settings.set_max_distance(1000);
pf_settings.set_max_cost(1000 * 50);
pf_settings.set_avoid_dangerous_traps(true);
pf_settings.set_avoid_sharp(true);
pf_settings.set_size_restriction(creature_size::medium);
*path_settings = pf_settings;

move_mode = move_mode_walk;
next_expected_position = std::nullopt;
Expand Down Expand Up @@ -10010,7 +10017,7 @@ std::function<bool( const tripoint & )> Character::get_path_avoid() const
};
}

const pathfinding_settings &Character::get_pathfinding_settings() const
const PathfindingSettings &Character::get_pathfinding_settings() const
{
return *path_settings;
}
Expand Down
6 changes: 3 additions & 3 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ struct itype;
struct mutation_branch;
struct mutation_category_trait;
struct mutation_variant;
struct pathfinding_settings;
class PathfindingSettings;
struct projectile;
struct requirement_data;
struct tool_comp;
Expand Down Expand Up @@ -3278,7 +3278,7 @@ class Character : public Creature, public visitable
/** Returns the player's modified base movement cost */
int run_cost( int base_cost, bool diag = false ) const;

const pathfinding_settings &get_pathfinding_settings() const override;
const PathfindingSettings &get_pathfinding_settings() const override;
std::function<bool( const tripoint & )> get_path_avoid() const override;
/**
* Get all hostile creatures currently visible to this player.
Expand Down Expand Up @@ -4019,7 +4019,7 @@ class Character : public Creature, public visitable
* Cache for pathfinding settings.
* Most of it isn't changed too often, hence mutable.
*/
mutable pimpl<pathfinding_settings> path_settings;
mutable pimpl<PathfindingSettings> path_settings;

// faction API versions
// 2 - allies are in your_followers faction; NPCATT_FOLLOW is follower but not an ally
Expand Down
4 changes: 2 additions & 2 deletions src/creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class window;
} // namespace catacurses
struct dealt_projectile_attack;
struct field_immunity_data;
struct pathfinding_settings;
class PathfindingSettings;
struct projectile;
struct projectile_attack_results;
struct trap;
Expand Down Expand Up @@ -944,7 +944,7 @@ class Creature : public viewer
virtual units::mass weight_capacity() const;

/** Returns settings for pathfinding. */
virtual const pathfinding_settings &get_pathfinding_settings() const = 0;
virtual const PathfindingSettings &get_pathfinding_settings() const = 0;
/** Returns a set of points we do not want to path through. */
virtual std::function<bool( const tripoint & )> get_path_avoid() const = 0;

Expand Down
7 changes: 5 additions & 2 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4327,8 +4327,11 @@ Creature *game::is_hostile_within( int distance, bool dangerous )
if( critter->is_ranged_attacker() ) {
return critter;
}

const pathfinding_settings pf_settings = pathfinding_settings{ 8, distance, distance * 2, 4, true, true, false, true, false, false };
PathfindingSettings pf_settings;
pf_settings.set_bash_strength( 8 );
pf_settings.set_max_distance( distance );
pf_settings.set_max_cost( distance * 2 * 50 );
pf_settings.set_climb_cost( 4 );

if( !get_map().route( u.pos_bub(), critter->pos_bub(), pf_settings ).empty() ) {
return critter;
Expand Down
11 changes: 9 additions & 2 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5486,8 +5486,15 @@ std::pair<item *, tripoint_bub_ms> map::_add_item_or_charges( const tripoint_bub
std::vector<tripoint_bub_ms> tiles = closest_points_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, false, true, false,
false, false );
PathfindingSettings setting;
setting.set_avoid_bashing( true );
setting.set_max_distance( max_dist );
setting.set_max_cost( max_path_length * 50 );
setting.set_avoid_opening_doors( true );
setting.set_avoid_unlocking_doors( true );
setting.set_avoid_dangerous_traps( true );
setting.set_avoid_climb_stairway( true );

for( const tripoint_bub_ms &e : tiles ) {
if( copies_remaining <= 0 ) {
break;
Expand Down
12 changes: 6 additions & 6 deletions src/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class map;

enum class ter_furn_flag : int;
struct pathfinding_cache;
struct pathfinding_settings;
class PathfindingSettings;
template<typename T>
struct weighted_int_list;
struct field_proc_data;
Expand Down Expand Up @@ -769,12 +769,12 @@ class map
*/
// TODO: fix point types (remove the first overload)
std::vector<tripoint> route( const tripoint &f, const tripoint &t,
const pathfinding_settings &settings,
const PathfindingSettings &settings,
const std::function<bool( const tripoint & )> &avoid = []( const tripoint & ) {
return false;
} ) const;
std::vector<tripoint_bub_ms> route( const tripoint_bub_ms &f, const tripoint_bub_ms &t,
const pathfinding_settings &settings,
const PathfindingSettings &settings,
const std::function<bool( const tripoint & )> &avoid = []( const tripoint & ) {
return false;
} ) const;
Expand All @@ -789,17 +789,17 @@ class map
// Pathfinding cost helper that computes the cost of moving into |p| from |cur|.
// Includes climbing, bashing and opening doors.
int cost_to_pass( const tripoint_bub_ms &cur, const tripoint_bub_ms &p,
const pathfinding_settings &settings,
const PathfindingSettings &settings,
PathfindingFlags p_special ) const;
// Pathfinding cost helper that computes the cost of moving into |p|
// from |cur| based on perceived danger.
// Includes moving through traps.
int cost_to_avoid( const tripoint_bub_ms &cur, const tripoint_bub_ms &p,
const pathfinding_settings &settings,
const PathfindingSettings &settings,
PathfindingFlags p_special ) const;
// Sum of cost_to_pass and cost_to_avoid.
int extra_cost( const tripoint_bub_ms &cur, const tripoint_bub_ms &p,
const pathfinding_settings &settings,
const PathfindingSettings &settings,
PathfindingFlags p_special ) const;
public:

Expand Down
11 changes: 9 additions & 2 deletions src/monattack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1575,8 +1575,15 @@ bool mattack::triffid_heartbeat( monster *z )

map &here = get_map();
creature_tracker &creatures = get_creature_tracker();
static pathfinding_settings root_pathfind( 10, 20, 50, 0, false, false, false, false, false,
false );
// TODO: Move this to a separate initialiser.
static PathfindingSettings root_pathfind;
root_pathfind.set_bash_strength( 10 );
root_pathfind.set_max_distance( 20 );
root_pathfind.set_max_cost( 50 * 50 );
root_pathfind.set_avoid_opening_doors( true );
root_pathfind.set_avoid_unlocking_doors( true );
root_pathfind.set_avoid_climb_stairway( true );

if( rl_dist( z->pos_bub(), player_character.pos_bub() ) > 5 &&
!here.route( player_character.pos_bub(), z->pos_bub(), root_pathfind ).empty() ) {
add_msg( m_warning, _( "The root walls creak around you." ) );
Expand Down
10 changes: 5 additions & 5 deletions src/monmove.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,10 @@ bool monster::know_danger_at( const tripoint &p ) const

bool avoid_fire = avoid_simple || has_flag( mon_flag_PATH_AVOID_FIRE );
bool avoid_fall = avoid_simple || has_flag( mon_flag_PATH_AVOID_FALL );
bool avoid_sharp = avoid_simple || get_pathfinding_settings().avoid_sharp;
bool avoid_sharp = avoid_simple || get_pathfinding_settings().avoid_sharp();

bool avoid_dangerous_fields = get_pathfinding_settings().avoid_dangerous_fields;
bool avoid_traps = get_pathfinding_settings().avoid_traps;
bool avoid_dangerous_fields = get_pathfinding_settings().avoid_dangerous_fields();
bool avoid_traps = get_pathfinding_settings().avoid_dangerous_traps();

// technically this will shortcut in evaluation from fire or fall
// before hitting simple or complex but this is more explicit
Expand Down Expand Up @@ -1017,8 +1017,8 @@ void monster::move()
path.erase( path.begin() );
}

const pathfinding_settings &pf_settings = get_pathfinding_settings();
if( pf_settings.max_dist >= rl_dist( get_location(), get_dest() ) &&
const PathfindingSettings &pf_settings = get_pathfinding_settings();
if( pf_settings.max_distance() >= rl_dist( get_location(), get_dest() ) &&
( path.empty() || rl_dist( pos(), path.front() ) >= 2 || path.back() != local_dest.raw() ) ) {
// We need a new path
if( can_pathfind() ) {
Expand Down
8 changes: 4 additions & 4 deletions src/monster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ static const trait_id trait_PHEROMONE_MAMMAL( "PHEROMONE_MAMMAL" );
static const trait_id trait_TERRIFYING( "TERRIFYING" );
static const trait_id trait_THRESH_MYCUS( "THRESH_MYCUS" );

struct pathfinding_settings;
class PathfindingSettings;

// Limit the number of iterations for next upgrade_time calculations.
// This also sets the percentage of monsters that will never upgrade.
Expand Down Expand Up @@ -1483,8 +1483,8 @@ bool monster::has_intelligence() const
has_flag( mon_flag_PATH_AVOID_FIRE ) ||
has_flag( mon_flag_PATH_AVOID_DANGER ) ||
has_flag( mon_flag_PRIORITIZE_TARGETS ) ||
get_pathfinding_settings().avoid_sharp ||
get_pathfinding_settings().avoid_traps;
type->path_settings.avoid_sharp() ||
type->path_settings.avoid_dangerous_traps();
}

std::vector<material_id> monster::get_absorb_material() const
Expand Down Expand Up @@ -4052,7 +4052,7 @@ void monster::on_load()
name(), to_turns<int>( dt ), healed, healed_speed );
}

const pathfinding_settings &monster::get_pathfinding_settings() const
const PathfindingSettings &monster::get_pathfinding_settings() const
{
return type->path_settings;
}
Expand Down
4 changes: 2 additions & 2 deletions src/monster.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace catacurses
class window;
} // namespace catacurses
struct dealt_projectile_attack;
struct pathfinding_settings;
class PathfindingSettings;
struct trap;

enum class mon_trigger : int;
Expand Down Expand Up @@ -618,7 +618,7 @@ class monster : public Creature
*/
void on_load();

const pathfinding_settings &get_pathfinding_settings() const override;
const PathfindingSettings &get_pathfinding_settings() const override;
std::function<bool( const tripoint & )> get_path_avoid() const override;
double calculate_by_enchantment( double modify, enchant_vals::mod value,
bool round_output = false ) const;
Expand Down
45 changes: 32 additions & 13 deletions src/monstergenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -560,16 +560,16 @@ void MonsterGenerator::apply_species_attributes( mtype &mon )

void MonsterGenerator::finalize_pathfinding_settings( mtype &mon )
{
if( mon.path_settings.max_length < 0 ) {
mon.path_settings.max_length = mon.path_settings.max_dist * 5;
if( mon.path_settings.max_cost() / 50 < 0 ) {
mon.path_settings.set_max_cost( mon.path_settings.max_distance() * 5 * 50 ) ;
}

if( mon.path_settings.bash_strength < 0 ) {
mon.path_settings.bash_strength = mon.bash_skill;
if( mon.path_settings.bash_strength() < 0 ) {
mon.path_settings.set_bash_strength( mon.bash_skill );
}

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

Expand Down Expand Up @@ -1300,14 +1300,33 @@ void mtype::load( const JsonObject &jo, const std::string &src )
if( jo.has_member( "path_settings" ) ) {
JsonObject jop = jo.get_object( "path_settings" );
// Here rather than in pathfinding.cpp because we want monster-specific defaults and was_loaded
optional( jop, was_loaded, "max_dist", path_settings.max_dist, 0 );
optional( jop, was_loaded, "max_length", path_settings.max_length, -1 );
optional( jop, was_loaded, "bash_strength", path_settings.bash_strength, -1 );
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 );
optional( jop, was_loaded, "avoid_dangerous_fields", path_settings.avoid_dangerous_fields, false );
int max_dist;
int bash_strength;
int max_length;
bool allow_open_doors;
bool avoid_traps;
bool allow_climb_stairs;
bool avoid_sharp;
bool avoid_dangerous_fields;

optional( jop, was_loaded, "max_dist", max_dist, 0 );
optional( jop, was_loaded, "max_length", max_length, -1 );
optional( jop, was_loaded, "bash_strength", bash_strength, -1 );
optional( jop, was_loaded, "allow_open_doors", allow_open_doors, false );
optional( jop, was_loaded, "avoid_traps", avoid_traps, false );
optional( jop, was_loaded, "allow_climb_stairs", allow_climb_stairs, true );
optional( jop, was_loaded, "avoid_sharp", avoid_sharp, false );
optional( jop, was_loaded, "avoid_dangerous_fields", avoid_dangerous_fields, false );

path_settings = PathfindingSettings();
path_settings.set_max_distance( max_dist );
path_settings.set_bash_strength( bash_strength );
// FIXME: cost -> length conversion is a stopgap before the new pathfinding system is added.
path_settings.set_max_cost( max_length * 50 );
path_settings.set_avoid_opening_doors( !allow_open_doors );
path_settings.set_avoid_dangerous_traps( !avoid_traps );
path_settings.set_avoid_climb_stairway( !allow_climb_stairs );
path_settings.set_avoid_dangerous_fields( avoid_dangerous_fields );
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/mtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ struct mtype {
// Monster biosignature variables
std::optional<time_duration> biosig_timer;

pathfinding_settings path_settings;
PathfindingSettings path_settings;

// All the bools together for space efficiency
//
Expand Down
2 changes: 1 addition & 1 deletion src/mutation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ void Character::recalculate_size()
size_class = creature_size::medium;
}
}
path_settings->size = size_class;
path_settings->set_size_restriction( size_class );
}

void Character::mutation_effect( const trait_id &mut, const bool worn_destroyed_override )
Expand Down
24 changes: 16 additions & 8 deletions src/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,16 @@ npc::npc()
patience = 0;
attitude = NPCATT_NULL;

*path_settings = pathfinding_settings( 0, 1000, 1000, 10, true, true, true, true, false, true,
get_size() );
PathfindingSettings pf_settings;
pf_settings.set_avoid_bashing( true );
pf_settings.set_max_distance( 1000 );
pf_settings.set_max_cost( 1000 * 50 );
pf_settings.set_climb_cost( 10 );
pf_settings.set_avoid_dangerous_traps( true );
pf_settings.set_avoid_sharp( true );
pf_settings.set_size_restriction( get_size() );
*path_settings = pf_settings;

for( direction threat_dir : npc_threat_dir ) {
ai_cache.threat_map[ threat_dir ] = 0.0f;
}
Expand Down Expand Up @@ -3453,26 +3461,26 @@ bool npc::will_accept_from_player( const item &it ) const
return true;
}

const pathfinding_settings &npc::get_pathfinding_settings() const
const PathfindingSettings &npc::get_pathfinding_settings() const
{
return get_pathfinding_settings( false );
}

const pathfinding_settings &npc::get_pathfinding_settings( bool no_bashing ) const
const PathfindingSettings &npc::get_pathfinding_settings( bool no_bashing ) const
{
path_settings->bash_strength = no_bashing ? 0 : smash_ability();
path_settings->set_bash_strength( no_bashing ? 0 : smash_ability() );
if( has_trait( trait_NO_BASH ) ) {
path_settings->bash_strength = 0;
path_settings->set_bash_strength( 0 );
}
// 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.0f ) * climb / ( climb - 1 );
path_settings->set_climb_cost( ( 10 - climb / 5.0f ) * climb / ( climb - 1 ) );
} else {
// Climbing at this dexterity will always fail
path_settings->climb_cost = 0;
path_settings->set_climb_cost( 0 );
}

return *path_settings;
Expand Down
6 changes: 3 additions & 3 deletions src/npc.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class window;
struct bionic_data;
struct mission_type;
struct overmap_location;
struct pathfinding_settings;
class PathfindingSettings;

enum game_message_type : int;
class gun_mode;
Expand Down Expand Up @@ -1197,8 +1197,8 @@ class npc : public Character

void set_movement_mode( const move_mode_id &mode ) override;

const pathfinding_settings &get_pathfinding_settings() const override;
const pathfinding_settings &get_pathfinding_settings( bool no_bashing ) const;
const PathfindingSettings &get_pathfinding_settings() const override;
const PathfindingSettings &get_pathfinding_settings( bool no_bashing ) const;
std::function<bool( const tripoint & )> get_path_avoid() const override;

// Item discovery and fetching
Expand Down
Loading

0 comments on commit 0a9b8e8

Please sign in to comment.