Skip to content

Commit

Permalink
refactor: use optional for map_funcs::climbing_cost
Browse files Browse the repository at this point in the history
game
    - remove unnecessary cost <= 0 check (climbing_cost cannot be < 0)
iexamine
    - being hard to climb is now considered both_way
    - prevent redundant rope message when climbing down by hand
  • Loading branch information
scarf005 committed May 27, 2023
1 parent dfa3192 commit 877bac4
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 40 deletions.
9 changes: 5 additions & 4 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10026,9 +10026,10 @@ void game::vertical_move( int movez, bool force, bool peeking )
}
}

const int cost = map_funcs::climbing_cost( m, u.pos(), stairs );

if( cost == 0 ) {
const auto cost = map_funcs::climbing_cost( m, u.pos(), stairs );

if( !cost.has_value() ) {
if( u.has_trait( trait_WEB_ROPE ) ) {
if( pts.empty() ) {
add_msg( m_info, _( "There is nothing above you that you can attach a web to." ) );
Expand Down Expand Up @@ -10056,14 +10057,14 @@ void game::vertical_move( int movez, bool force, bool peeking )

}

if( cost <= 0 || pts.empty() ) {
if( pts.empty() ) {
add_msg( m_info,
_( "You can't climb here - there is no terrain above you that would support your weight." ) );
return;
} else {
// TODO: Make it an extended action
climbing = true;
move_cost = cost;
move_cost = cost.value();

const std::optional<tripoint> pnt = point_selection_menu( pts );
if( !pnt ) {
Expand Down
76 changes: 45 additions & 31 deletions src/iexamine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "bionics.h"
#include "bodypart.h"
#include "calendar.h"
#include "cata_unreachable.h"
#include "cata_utility.h"
#include "catacharset.h"
#include "character.h"
Expand Down Expand Up @@ -4658,7 +4659,7 @@ void iexamine::ledge( player &p, const tripoint &examp )
}

const bool has_grapnel = p.has_amount( itype_grapnel, 1 );
const int climb_cost = map_funcs::climbing_cost( here, where, examp );
const auto climb_cost = map_funcs::climbing_cost( here, where, examp );
const auto fall_mod = p.fall_damage_mod();
const std::string query_str = vgettext( "Looks like %d story. Jump down?",
"Looks like %d stories. Jump down?",
Expand All @@ -4667,47 +4668,60 @@ void iexamine::ledge( player &p, const tripoint &examp )
if( height > 1 && !query_yn( query_str.c_str(), height ) ) {
return;
} else if( height == 1 ) {
enum class climb_result { dangerous_one_way, safe_one_way, safe, safe_difficult };
const auto get_status = [&]() {
enum class climb_result {
one_way_dangerous, one_way_unclimbable,
both_way_safe, both_way_grapnel, both_way_hard_to_climb,
};
const auto get_climb_result = [&]() {
if( has_grapnel ) {
return climb_result::safe;
} else if( climb_cost <= 0 && fall_mod > 0.8 ) {
return climb_result::dangerous_one_way;
} else if( climb_cost <= 0 ) {
return climb_result::safe_one_way;
} else if( climb_cost < 200 ) {
return climb_result::safe;
return climb_result::both_way_grapnel;
}
if( climb_cost.has_value() ) {
return climb_cost.value() < 200
? climb_result::both_way_safe
: climb_result::both_way_hard_to_climb;
} else {
return climb_result::safe_difficult;
return fall_mod > 0.8
? climb_result::one_way_dangerous
: climb_result::one_way_unclimbable;
}
};
const auto status = get_status();
if( status != climb_result::safe ) {
const auto get_query = [&]() {
switch( status ) {
case climb_result::dangerous_one_way:
return _( "You probably won't be able to get up and jumping down may hurt. Jump?" );
case climb_result::safe_one_way:
return _( "You probably won't be able to get back up. Climb down?" );
case climb_result::safe_difficult:
return _( "You may have problems climbing back up. Climb down?" );
default:
throw std::logic_error( "unreachable" );
}
};
if( !query_yn( get_query() ) ) {
return;
const auto get_message = []( climb_result res ) {
switch( res ) {
case climb_result::both_way_safe:
return _( "You climb down." );
case climb_result::both_way_grapnel:
return _( "You tie the rope around your waist and begin to climb down." );
case climb_result::both_way_hard_to_climb:
return _( "You climb down but feel that it won't be easy to climb back up." );
case climb_result::one_way_dangerous:
return _( "You probably won't be able to get up and jumping down may hurt. Jump?" );
case climb_result::one_way_unclimbable:
return _( "You probably won't be able to get back up. Climb down?" );
}
cata::unreachable();
};
add_msg( m_debug, "climb_cost: %d", climb_cost.value_or( -1 ) );
const auto result = get_climb_result();
const auto message = get_message( result );
switch( result ) {
case climb_result::both_way_safe:
case climb_result::both_way_grapnel:
case climb_result::both_way_hard_to_climb:
p.add_msg_if_player( message );
break;
case climb_result::one_way_dangerous:
case climb_result::one_way_unclimbable:
default:
if( !query_yn( message ) ) {
return;
}
}
}

p.moves -= to_moves<int>( 1_seconds + 1_seconds * fall_mod );
p.setpos( examp );

if( has_grapnel ) {
p.add_msg_if_player( _( "You tie the rope around your waist and begin to climb down." ) );
}

if( climb_cost > 0 || rng_float( 0.8, 1.0 ) > fall_mod ) {
// One tile of falling less (possibly zero)
g->vertical_move( -1, true );
Expand Down
6 changes: 3 additions & 3 deletions src/map_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ static const mtype_id mon_mi_go_myrmidon( "mon_mi_go_myrmidon" );
namespace map_funcs
{

int climbing_cost( const map &m, const tripoint &from, const tripoint &to )
auto climbing_cost( const map &m, const tripoint &from, const tripoint &to ) -> std::optional<int>
{
// TODO: All sorts of mutations, equipment weight etc. for characters
if( !m.valid_move( from, to, false, true ) ) {
return 0;
return {};
}
const int diff = m.climb_difficulty( from );
if( diff > 5 ) {
return 0;
return {};
}
return 50 + diff * 100;
}
Expand Down
4 changes: 2 additions & 2 deletions src/map_functions.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include <optional>
#ifndef CATA_SRC_MAP_FUNCTIONS_H
#define CATA_SRC_MAP_FUNCTIONS_H

Expand All @@ -11,10 +12,9 @@ namespace map_funcs
/**
* Checks both the neighborhoods of from and to for climbable surfaces,
* returns move cost of climbing from `from` to `to`.
* 0 means climbing is not possible.
* Return value can depend on the orientation of the terrain.
*/
int climbing_cost( const map &m, const tripoint &from, const tripoint &to );
auto climbing_cost( const map &m, const tripoint &from, const tripoint &to ) -> std::optional<int>;

void migo_nerve_cage_removal( map &m, const tripoint &p, bool spawn_damaged );

Expand Down

0 comments on commit 877bac4

Please sign in to comment.