From ac4daa91ff8442deb4dc16fc8d25b7117499dc6e Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Tue, 11 Jun 2019 07:20:35 +0000 Subject: [PATCH] Avoid retrieving get_vehicles() multiple times per turn --- src/map.cpp | 50 +++++++++++++++++++++----------------------- src/map.h | 4 ++-- src/vehicle.h | 4 ++-- src/vehicle_move.cpp | 19 +++++++++-------- 4 files changed, 38 insertions(+), 39 deletions(-) diff --git a/src/map.cpp b/src/map.cpp index 62551958fdf65..22f252dbc8ae6 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -360,26 +360,23 @@ void map::on_vehicle_moved( const int smz ) void map::vehmove() { // give vehicles movement points - { - VehicleList vehs = get_vehicles(); - for( auto &vehs_v : vehs ) { - vehicle *veh = vehs_v.v; - veh->gain_moves(); - veh->slow_leak(); - } + VehicleList vehicle_list = get_vehicles(); + for( auto &vehs_v : vehicle_list ) { + vehicle *veh = vehs_v.v; + veh->gain_moves(); + veh->slow_leak(); } // 15 equals 3 >50mph vehicles, or up to 15 slow (1 square move) ones // But 15 is too low for V12 death-bikes, let's put 100 here for( int count = 0; count < 100; count++ ) { - if( !vehproceed() ) { + if( !vehproceed( vehicle_list ) ) { break; } } // Process item removal on the vehicles that were modified this turn. // Use a copy because part_removal_cleanup can modify the container. auto temp = dirty_vehicle_list; - VehicleList vehicle_list = get_vehicles(); for( const auto &elem : temp ) { auto same_ptr = [ elem ]( const struct wrapped_vehicle & tgt ) { return elem == tgt.v; @@ -392,25 +389,23 @@ void map::vehmove() dirty_vehicle_list.clear(); } -bool map::vehproceed() +bool map::vehproceed( VehicleList &vehs ) { - VehicleList vehs = get_vehicles(); - vehicle *cur_veh = nullptr; + wrapped_vehicle *cur_veh = nullptr; float max_of_turn = 0; // First horizontal movement - for( auto &vehs_v : vehs ) { + for( wrapped_vehicle &vehs_v : vehs ) { if( vehs_v.v->of_turn > max_of_turn ) { - cur_veh = vehs_v.v; - max_of_turn = cur_veh->of_turn; + cur_veh = &vehs_v; + max_of_turn = cur_veh->v->of_turn; } } // Then vertical-only movement if( cur_veh == nullptr ) { - for( auto &vehs_v : vehs ) { - vehicle &cveh = *vehs_v.v; - if( cveh.is_falling ) { - cur_veh = vehs_v.v; + for( wrapped_vehicle &vehs_v : vehs ) { + if( vehs_v.v->is_falling ) { + cur_veh = &vehs_v; break; } } @@ -420,7 +415,8 @@ bool map::vehproceed() return false; } - return cur_veh->act_on_map(); + cur_veh->v = cur_veh->v->act_on_map(); + return true; } static bool sees_veh( const Creature &c, vehicle &veh, bool force_recalc ) @@ -431,18 +427,18 @@ static bool sees_veh( const Creature &c, vehicle &veh, bool force_recalc ) } ); } -void map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &facing ) +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 ); - return; + return &veh; } if( dp.z + veh.smz < -OVERMAP_DEPTH || dp.z + veh.smz > OVERMAP_HEIGHT ) { - return; + return &veh; } veh.precalc_mounts( 1, veh.skidding ? veh.turn_dir : facing.dir(), veh.pivot_point() ); @@ -462,7 +458,7 @@ void map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &facing if( velocity_before == 0 ) { debugmsg( "%s tried to move %s with no velocity", veh.name, vertical ? "vertically" : "horizontally" ); - return; + return &veh; } bool veh_veh_coll_flag = false; @@ -527,7 +523,7 @@ void map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &facing if( veh_veh_coll_flag ) { // Break here to let the hit vehicle move away - return; + return &veh; } // If not enough wheels, mess up the ground a bit. @@ -574,6 +570,7 @@ void map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &facing const bool seen = sees_veh( g->u, veh, false ); + vehicle *new_vehicle = &veh; if( can_move ) { // Accept new direction if( veh.skidding ) { @@ -590,7 +587,7 @@ void map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &facing veh.on_move(); // Actually change position tripoint pt = veh.global_pos3(); // displace_vehicle needs a non-const reference - displace_vehicle( pt, dp1 ); + new_vehicle = displace_vehicle( pt, dp1 ); } else if( !vertical ) { veh.stop(); } @@ -609,6 +606,7 @@ void map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &facing g->draw(); refresh_display(); } + return new_vehicle; } float map::vehicle_vehicle_collision( vehicle &veh, vehicle &veh2, diff --git a/src/map.h b/src/map.h index 82411fb0944e2..cbb3c5927cc96 100644 --- a/src/map.h +++ b/src/map.h @@ -533,7 +533,7 @@ class map // Vehicle movement void vehmove(); // Selects a vehicle to move, returns false if no moving vehicles - bool vehproceed(); + bool vehproceed( VehicleList &vehs ); // 3D vehicles VehicleList get_vehicles( const tripoint &start, const tripoint &end ); @@ -574,7 +574,7 @@ class map // Actually moves the vehicle // Unlike displace_vehicle, this one handles collisions - void move_vehicle( vehicle &veh, const tripoint &dp, const tileray &facing ); + vehicle *move_vehicle( vehicle &veh, const tripoint &dp, const tileray &facing ); // Furniture: 2D overloads void set( const int x, const int y, const ter_id &new_terrain, const furn_id &new_furniture ); diff --git a/src/vehicle.h b/src/vehicle.h index 034c6fd8af6d4..6d380aa44e574 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -1454,8 +1454,8 @@ class vehicle rl_vec2d dir_vec() const; // update vehicle parts as the vehicle moves void on_move(); - // move the vehicle on the map - bool act_on_map(); + // move the vehicle on the map. Returns updated pointer to self. + vehicle *act_on_map(); // check if the vehicle should be falling or is in water void check_falling_or_floating(); diff --git a/src/vehicle_move.cpp b/src/vehicle_move.cpp index ed953f2e7a749..f3bf9dc49c725 100644 --- a/src/vehicle_move.cpp +++ b/src/vehicle_move.cpp @@ -1247,7 +1247,7 @@ bool vehicle::is_wheel_state_correct_to_turn_on_rails( int wheels_on_rail, int w // allow turn for vehicles with wheel distance < 4 when moving backwards } -bool vehicle::act_on_map() +vehicle *vehicle::act_on_map() { const tripoint pt = global_pos3(); if( !g->m.inbounds( pt ) ) { @@ -1256,7 +1256,7 @@ bool vehicle::act_on_map() stop( false ); of_turn = 0; is_falling = false; - return true; + return this; } const bool pl_ctrl = player_in_control( g->u ); @@ -1273,7 +1273,7 @@ bool vehicle::act_on_map() g->m.on_vehicle_moved( smz ); // Destroy vehicle (sank to nowhere) g->m.destroy_vehicle( this ); - return true; + return this; } // It needs to fall when it has no support OR was falling before @@ -1301,7 +1301,7 @@ bool vehicle::act_on_map() if( !should_fall && abs( velocity ) < 20 ) { stop(); of_turn -= .321f; - return true; + return this; } const float wheel_traction_area = g->m.vehicle_wheel_traction( *this ); @@ -1315,7 +1315,7 @@ bool vehicle::act_on_map() } else { add_msg( m_info, _( "Your %s is beached." ), name ); } - return true; + return this; } } const float turn_cost = vehicles::vmiph_per_tile / std::max( 0.0001f, abs( velocity ) ); @@ -1327,7 +1327,7 @@ bool vehicle::act_on_map() if( !should_fall ) { of_turn_carry = of_turn; of_turn = 0; - return true; + return this; } falling_only = true; } @@ -1404,17 +1404,18 @@ bool 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 ) { - g->m.move_vehicle( *this, tripoint( dp.x, dp.y, 0 ), mdir ); + new_pointer = g->m.move_vehicle( *new_pointer, tripoint( dp.x, dp.y, 0 ), mdir ); } if( dp.z != 0 ) { - g->m.move_vehicle( *this, tripoint( 0, 0, dp.z ), mdir ); + new_pointer = g->m.move_vehicle( *new_pointer, tripoint( 0, 0, dp.z ), mdir ); is_falling = false; } - return true; + return new_pointer; } void vehicle::check_falling_or_floating()