diff --git a/src/map.cpp b/src/map.cpp index 303fffe70e549..829abfa892dd7 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -434,14 +434,33 @@ static bool sees_veh( const Creature &c, vehicle &veh, bool force_recalc ) vehicle *map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &facing ) { - const bool vertical = dp.z != 0; - if( ( dp.x == 0 && dp.y == 0 && dp.z == 0 ) || - ( abs( dp.x ) > 1 || abs( dp.y ) > 1 || abs( dp.z ) > 1 ) || - ( vertical && ( dp.x != 0 || dp.y != 0 ) ) ) { - debugmsg( "move_vehicle called with %d,%d,%d displacement vector", dp.x, dp.y, dp.z ); + if( dp == tripoint_zero ) { + debugmsg( "Empty displacement vector" ); + return &veh; + } else if( abs( dp.x ) > 1 || abs( dp.y ) > 1 || abs( dp.z ) > 1 ) { + debugmsg( "Invalid displacement vector: %d, %d, %d", dp.x, dp.y, dp.z ); return &veh; } + // Split the movement into horizontal and vertical for easier processing + if( dp.xy() != point_zero && dp.z != 0 ) { + vehicle *const new_pointer = move_vehicle( veh, tripoint( dp.xy(), 0 ), facing ); + if( !new_pointer ) { + return nullptr; + } + + vehicle *const result = move_vehicle( *new_pointer, tripoint( 0, 0, dp.z ), facing ); + if( !result ) { + return nullptr; + } + + result->is_falling = false; + return result; + } + const bool vertical = dp.z != 0; + // Ensured by the splitting above + assert( vertical == ( dp.xy() == point_zero ) ); + const int target_z = dp.z + veh.sm_pos.z; if( target_z < -OVERMAP_DEPTH || target_z > OVERMAP_HEIGHT ) { return &veh; diff --git a/src/monmove.cpp b/src/monmove.cpp index e6116660ea521..b71c0145dd455 100644 --- a/src/monmove.cpp +++ b/src/monmove.cpp @@ -1876,6 +1876,9 @@ void monster::shove_vehicle( const tripoint &remote_destination, veh.skidding = true; veh.velocity = shove_velocity; if( shove_destination != tripoint_zero ) { + if( shove_destination.z != 0 ) { + veh.vertical_velocity = shove_destination.z < 0 ? -shove_velocity : +shove_velocity; + } g->m.move_vehicle( veh, shove_destination, veh.face ); } veh.move = tileray( destination_delta_x, destination_delta_y ); diff --git a/src/vehicle_move.cpp b/src/vehicle_move.cpp index 3ecc5045dae30..d5b34ca5ed5f1 100644 --- a/src/vehicle_move.cpp +++ b/src/vehicle_move.cpp @@ -1335,18 +1335,7 @@ vehicle *vehicle::act_on_map() dp.z = -1; } - vehicle *new_pointer = this; - // Split the movement into horizontal and vertical for easier processing - if( dp.x != 0 || dp.y != 0 ) { - new_pointer = g->m.move_vehicle( *new_pointer, tripoint( dp.xy(), 0 ), mdir ); - } - - if( new_pointer != nullptr && dp.z != 0 ) { - new_pointer = g->m.move_vehicle( *new_pointer, tripoint( 0, 0, dp.z ), mdir ); - is_falling = false; - } - - return new_pointer; + return g->m.move_vehicle( *this, dp, mdir ); } void vehicle::check_falling_or_floating()