1 #include <vector>
2 
3 #include "avatar.h"
4 #include "catch/catch.hpp"
5 #include "character.h"
6 #include "damage.h"
7 #include "enums.h"
8 #include "item.h"
9 #include "map.h"
10 #include "map_helpers.h"
11 #include "optional.h"
12 #include "point.h"
13 #include "type_id.h"
14 #include "units.h"
15 #include "vehicle.h"
16 
17 TEST_CASE( "detaching_vehicle_unboards_passengers" )
18 {
19     clear_map();
20     const tripoint test_origin( 60, 60, 0 );
21     const tripoint vehicle_origin = test_origin;
22     map &here = get_map();
23     Character &player_character = get_player_character();
24     vehicle *veh_ptr = here.add_vehicle( vproto_id( "bicycle" ), vehicle_origin, -90_degrees, 0,
25                                          0 );
26     here.board_vehicle( test_origin, &player_character );
27     REQUIRE( player_character.in_vehicle );
28     here.detach_vehicle( veh_ptr );
29     REQUIRE( !player_character.in_vehicle );
30 }
31 
32 TEST_CASE( "destroy_grabbed_vehicle_section" )
33 {
34     GIVEN( "A vehicle grabbed by the player" ) {
35         map &here = get_map();
36         const tripoint test_origin( 60, 60, 0 );
37         avatar &player_character = get_avatar();
38         player_character.setpos( test_origin );
39         const tripoint vehicle_origin = test_origin + tripoint_south_east;
40         vehicle *veh_ptr = here.add_vehicle( vproto_id( "bicycle" ), vehicle_origin, -90_degrees,
41                                              0, 0 );
42         REQUIRE( veh_ptr != nullptr );
43         tripoint grab_point = test_origin + tripoint_east;
44         player_character.grab( object_type::VEHICLE, tripoint_east );
45         REQUIRE( player_character.get_grab_type() == object_type::VEHICLE );
46         REQUIRE( player_character.grab_point == tripoint_east );
47         WHEN( "The vehicle section grabbed by the player is destroyed" ) {
48             here.destroy( grab_point );
49             REQUIRE( veh_ptr->get_parts_at( grab_point, "", part_status_flag::available ).empty() );
50             THEN( "The player's grab is released" ) {
51                 CHECK( player_character.get_grab_type() == object_type::NONE );
52                 CHECK( player_character.grab_point == tripoint_zero );
53             }
54         }
55     }
56 }
57 
58 TEST_CASE( "add_item_to_broken_vehicle_part" )
59 {
60     clear_map();
61     const tripoint test_origin( 60, 60, 0 );
62     const tripoint vehicle_origin = test_origin;
63     vehicle *veh_ptr = get_map().add_vehicle( vproto_id( "bicycle" ), vehicle_origin, 0_degrees,
64                        0, 0 );
65     REQUIRE( veh_ptr != nullptr );
66 
67     const tripoint pos = vehicle_origin + tripoint_west;
68     auto cargo_parts = veh_ptr->get_parts_at( pos, "CARGO", part_status_flag::any );
69     REQUIRE( !cargo_parts.empty( ) );
70     vehicle_part *cargo_part = cargo_parts.front();
71     REQUIRE( cargo_part != nullptr );
72     //Must not be broken yet
73     REQUIRE( !cargo_part->is_broken() );
74     //For some reason (0 - cargo_part->hp()) is just not enough to destroy a part
75     REQUIRE( veh_ptr->mod_hp( *cargo_part, -( 1 + cargo_part->hp() ), damage_type::BASH ) );
76     //Now it must be broken
77     REQUIRE( cargo_part->is_broken() );
78     //Now part is really broken, adding an item should fail
79     const item itm2 = item( "jeans" );
80     REQUIRE( !veh_ptr->add_item( *cargo_part, itm2 ) );
81 }
82 
83 TEST_CASE( "starting_bicycle_damaged_pedal" )
84 {
85     clear_map();
86     const tripoint test_origin( 60, 60, 0 );
87     const tripoint vehicle_origin = test_origin;
88     map &here = get_map();
89     Character &player_character = get_player_character();
90     vehicle *veh_ptr = here.add_vehicle( vproto_id( "bicycle" ), vehicle_origin, -90_degrees, 0,
91                                          0 );
92     here.board_vehicle( test_origin, &player_character );
93     REQUIRE( player_character.in_vehicle );
94     REQUIRE( veh_ptr->engines.size() == 1 );
95 
96     vehicle_part &pedel = veh_ptr->part( veh_ptr->engines[ 0 ] );
97 
98     SECTION( "when the pedal has 1/4 hp" ) {
99         veh_ptr->set_hp( pedel, pedel.hp() * 0.25 );
100         // Try starting the engine 100 time because it is random that a combustion engine does fails
101         for( int i = 0; i < 100 ; i++ ) {
102             CHECK( veh_ptr->start_engine( 0 ) );
103         }
104     }
105 
106     SECTION( "when the pedal has 0 hp" ) {
107         veh_ptr->set_hp( pedel, 0 );
108 
109         CHECK_FALSE( veh_ptr->start_engine( 0 ) );
110     }
111 
112     here.detach_vehicle( veh_ptr );
113 }
114