From 7ef06afe8467da447b3c3c1c5d5f0907d3fc341f Mon Sep 17 00:00:00 2001 From: Brambor Date: Mon, 24 Jun 2024 16:09:04 +0200 Subject: [PATCH 1/2] Travel to: fix travel to on ramps --- src/action.cpp | 19 ++++++++++++------- src/action.h | 8 ++------ src/character.cpp | 17 +++++++++-------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/action.cpp b/src/action.cpp index 24d00b4394038..f20ec10bdaeba 100644 --- a/src/action.cpp +++ b/src/action.cpp @@ -555,12 +555,6 @@ std::optional press_x_if_bound( action_id act ) action_id get_movement_action_from_delta( const tripoint &d, const iso_rotate rot ) { - if( d.z == -1 ) { - return ACTION_MOVE_DOWN; - } else if( d.z == 1 ) { - return ACTION_MOVE_UP; - } - const bool iso_mode = rot == iso_rotate::yes && g->is_tileset_isometric(); if( d.xy() == point_north ) { return iso_mode ? ACTION_MOVE_FORTH_LEFT : ACTION_MOVE_FORTH; @@ -576,9 +570,20 @@ action_id get_movement_action_from_delta( const tripoint &d, const iso_rotate ro return iso_mode ? ACTION_MOVE_BACK : ACTION_MOVE_BACK_LEFT; } else if( d.xy() == point_west ) { return iso_mode ? ACTION_MOVE_BACK_LEFT : ACTION_MOVE_LEFT; - } else { + } else if( d.xy() == point_north_west ) { return iso_mode ? ACTION_MOVE_LEFT : ACTION_MOVE_FORTH_LEFT; } + + // Check z location last. + // If auto-moving over ramps, we need the character to move the xy directions. + // The z-movement is caused by the ramp automatically. + if( d.z == -1 ) { + return ACTION_MOVE_DOWN; + } else if( d.z == 1 ) { + return ACTION_MOVE_UP; + } + + return ACTION_NULL; } point get_delta_from_movement_action( const action_id act, const iso_rotate rot ) diff --git a/src/action.h b/src/action.h index 2e943e36519be..31819e34f5a5c 100644 --- a/src/action.h +++ b/src/action.h @@ -594,13 +594,9 @@ enum class iso_rotate : int { * that would generated that delta. See @ref action_id for the list of available movement * commands that may be generated. This function takes iso mode into account. * - * The only valid values for the coordinates of \p d are -1, 0 and 1 - * * @note: This function does not sanitize its inputs, which can result in some strange behavior: - * 1. If d.z is valid and non-zero, then d.x and d.y are ignored. - * 2. If d.z is invalid, it is treated as if it were zero. - * 3. If d.z is 0 or invalid, then any invalid d.x or d.y results in @ref ACTION_MOVE_FORTH_LEFT - * 4. If d.z is 0 or invalid, then a d.x == d.y == 0 results in @ref ACTION_MOVE_FORTH_LEFT + * 1. If d.x, d.y are valid and non-zero, then d.z is ignored. + * 2. If d.x, d.y and d.z are invalid or zero, then result is @ref ACTION_NULL * * @param[in] d coordinate delta, each coordinate should be -1, 0, or 1 * @returns ID of corresponding move action (usually... see note above) diff --git a/src/character.cpp b/src/character.cpp index 55bf924cb8916..6103f7f30c2c7 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -11460,7 +11460,15 @@ action_id Character::get_next_auto_move_direction() } if( next_expected_position ) { - if( pos_bub() != *next_expected_position ) { + // Difference between where the character is and where we expect them to be after last auto-move. + tripoint diff = ( pos_bub() - *next_expected_position ).raw().abs(); + // This might differ by 1 (in z-direction), since the character might have crossed a ramp, + // which teleported them a tile up or down. If the error is in x or y direction, we might as well + // give them a turn to recover, as the move still might be vaild. + // We cut off at 1 since 2 definitely results in an invalid move. + // If the character is still stumbling or stuck, + // they will cancel the auto-move on the next cycle (as the distance increases). + if( std::max( { diff.x, diff.y, diff.z } ) > 1 ) { // We're off course, possibly stumbling or stuck, cancel auto move return ACTION_NULL; } @@ -11471,13 +11479,6 @@ action_id Character::get_next_auto_move_direction() tripoint_rel_ms dp = *next_expected_position - pos_bub(); - // Make sure the direction is just one step and that - // all diagonal moves have 0 z component - if( std::abs( dp.x() ) > 1 || std::abs( dp.y() ) > 1 || std::abs( dp.z() ) > 1 || - ( dp.z() != 0 && ( dp.x() != 0 || dp.y() != 0 ) ) ) { - // Should never happen, but check just in case - return ACTION_NULL; - } // TODO: fix point types return get_movement_action_from_delta( dp.raw(), iso_rotate::yes ); } From 84aac80fd4e1cdbac01fb62335e5822bbba010ca Mon Sep 17 00:00:00 2001 From: Brambor Date: Mon, 24 Jun 2024 21:52:08 +0200 Subject: [PATCH 2/2] rename local var --- src/game.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 1ca52e5da2dbf..ce0d0648fc65e 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -11584,12 +11584,12 @@ bool game::grabbed_furn_move( const tripoint &dp ) return false; } - int ramp_offset = 0; + int ramp_z_offset = 0; // Furniture could be on a ramp at different time than player so adjust for that. if( m.has_flag( ter_furn_flag::TFLAG_RAMP_UP, fpos + tripoint( dp.xy(), 0 ) ) ) { - ramp_offset = 1; + ramp_z_offset = 1; } else if( m.has_flag( ter_furn_flag::TFLAG_RAMP_DOWN, fpos + tripoint( dp.xy(), 0 ) ) ) { - ramp_offset = -1; + ramp_z_offset = -1; } const bool pushing_furniture = dp.xy() == u.grab_point.xy(); @@ -11597,7 +11597,7 @@ bool game::grabbed_furn_move( const tripoint &dp ) const bool shifting_furniture = !pushing_furniture && !pulling_furniture; // Intended destination of furniture. - const tripoint fdest = fpos + tripoint( dp.xy(), ramp_offset ); + const tripoint fdest = fpos + tripoint( dp.xy(), ramp_z_offset ); // Unfortunately, game::is_empty fails for tiles we're standing on, // which will forbid pulling, so: @@ -11737,7 +11737,7 @@ bool game::grabbed_furn_move( const tripoint &dp ) return true; } - u.grab_point.z += ramp_offset; + u.grab_point.z += ramp_z_offset; if( shifting_furniture ) { // We didn't move