Skip to content

Commit

Permalink
Travel to: fix travel to on ramps
Browse files Browse the repository at this point in the history
  • Loading branch information
Brambor committed Jun 24, 2024
1 parent ae7671a commit 7ef06af
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 21 deletions.
19 changes: 12 additions & 7 deletions src/action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,12 +555,6 @@ std::optional<std::string> 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;
Expand All @@ -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 )
Expand Down
8 changes: 2 additions & 6 deletions src/action.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
17 changes: 9 additions & 8 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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 );
}
Expand Down

0 comments on commit 7ef06af

Please sign in to comment.