Skip to content

Commit

Permalink
Adjust tests for multiple folding vehicles and multiple tools
Browse files Browse the repository at this point in the history
  • Loading branch information
irwiss committed Aug 29, 2022
1 parent a26ad6b commit de51069
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 82 deletions.
2 changes: 1 addition & 1 deletion data/json/items/tool/unfoldable.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"copy-from": "generic_folded_vehicle",
"name": { "str": "folded Bicycle" },
"description": "A folded Bicycle.",
"weight": "20790 g",
"weight": "20786 g",
"volume": "18500 ml",
"symbol": "0",
"color": "light_gray",
Expand Down
189 changes: 108 additions & 81 deletions tests/vehicle_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
#include "vehicle.h"
#include "veh_type.h"


static const itype_id itype_folded_bicycle( "folded_bicycle" );
static const itype_id itype_folded_inflatable_boat( "folded_inflatable_boat" );
static const itype_id itype_folded_wheelchair_generic( "folded_wheelchair_generic" );
static const itype_id itype_hand_pump( "hand_pump" );

static const vproto_id vehicle_prototype_bicycle( "bicycle" );
Expand Down Expand Up @@ -121,112 +122,134 @@ TEST_CASE( "starting_bicycle_damaged_pedal" )
here.detach_vehicle( veh_ptr );
}

static void unfold_and_check( double damage, double degradation,
double expect_damage, double expect_degradation, double expected_hp )
struct vehicle_preset {
itype_id vehicle_itype_id; // folding vehicle to test
std::vector<itype_id> tool_itype_ids; // tool to grant
};

struct damage_preset {
double damage;
double degradation;
double expect_damage;
double expect_degradation;
double expect_hp;
};

static void complete_activity( Character &u, const activity_actor &act )
{
u.assign_activity( player_activity( act ) );
while( !u.activity.is_null() ) {
u.set_moves( u.get_speed() );
u.activity.do_turn( u );
}
}

static void unfold_and_check( const vehicle_preset &veh_preset, const damage_preset &damage_preset )
{
map &m = get_map();
Character &u = get_player_character();

clear_avatar();
clear_map();
clear_vehicles( &m );
u.move_to( u.get_location() + tripoint( 1, 0, 0 ) );
item boat_item( itype_folded_inflatable_boat );
item hand_pump( itype_hand_pump );
const units::volume boat_item_volume = boat_item.volume();
const units::mass boat_item_weight = boat_item.weight();
CAPTURE( damage, degradation, expect_damage, expect_degradation, expected_hp );
INFO( "unfold inflatable boat sourced from item factory without hand pump" );
{
u.assign_activity( player_activity( vehicle_unfolding_activity_actor( boat_item ) ) );
while( !u.activity.is_null() ) {
u.set_moves( u.get_speed() );
u.activity.do_turn( u );
}

// should fail as avatar has no hand_pump
REQUIRE( !m.veh_at( u.get_location() ).has_value() );
u.worn.wear_item( u, item( "debug_backpack" ), false, false );

item veh_item( veh_preset.vehicle_itype_id );

// the folded item should drop and should be deleted
map_stack map_items = m.i_at( u.pos_bub() );
REQUIRE( map_items.size() == 1 );
map_items.clear();
// save these to compare against player folded item later
const units::volume factory_item_volume = veh_item.volume();
const units::mass factory_item_weight = veh_item.weight();

CAPTURE( veh_preset.vehicle_itype_id.str() );
for( const itype_id &tool_itype_id : veh_preset.tool_itype_ids ) {
CAPTURE( tool_itype_id.str() );
}
CAPTURE( damage_preset.damage, damage_preset.degradation, damage_preset.expect_damage,
damage_preset.expect_degradation, damage_preset.expect_hp );

INFO( "unfold inflatable boat sourced from item factory with hand pump" );
{
u.wield( hand_pump ); // give hand_pump
if( !veh_preset.tool_itype_ids.empty() ) {
INFO( "unfolding vehicle should fail without required tool" );
{
complete_activity( u, vehicle_unfolding_activity_actor( veh_item ) );

u.assign_activity( player_activity( vehicle_unfolding_activity_actor( boat_item ) ) );
while( !u.activity.is_null() ) {
u.set_moves( u.get_speed() );
u.activity.do_turn( u );
}
// should have no value because avatar has no required tool to unfold
REQUIRE( !m.veh_at( u.get_location() ).has_value() );

// should succeed now avatar has hand_pump
optional_vpart_position boat_part = m.veh_at( u.get_location() );
REQUIRE( boat_part.has_value() );

// set damage/degradation on every part
vehicle &veh = boat_part->vehicle();
for( const vpart_reference &vpr : veh.get_all_parts() ) {
item base = vpr.part().get_base();
base.set_degradation( degradation * base.max_damage() );
base.set_damage( damage * base.max_damage() );
vpr.part().set_base( base );
veh.set_hp( vpr.part(), vpr.info().durability, true );
// the folded item should drop and needs to be deleted from the map
map_stack map_items = m.i_at( u.pos_bub() );
REQUIRE( map_items.size() == 1 );
map_items.clear();
}
}

// fold into an item
u.assign_activity( player_activity( vehicle_folding_activity_actor( veh ) ) );
while( !u.activity.is_null() ) {
u.set_moves( u.get_speed() );
u.activity.do_turn( u );
}
INFO( "unfolding vehicle item sourced from item factory" );

// should fail as vehicle is now folded into item
REQUIRE( !m.veh_at( u.get_location() ).has_value() );
// spawn unfolding tools
for( const itype_id &tool_itype_id : veh_preset.tool_itype_ids ) {
u.inv->add_item( item( tool_itype_id ) );
}

map_stack map_items = m.i_at( u.pos_bub() );
REQUIRE( map_items.size() == 1 );
item player_folded_boat = map_items.only_item();
map_items.clear();
complete_activity( u, vehicle_unfolding_activity_actor( veh_item ) );

// check player-folded boat has same volume/weight as item factory one
CHECK( boat_item_volume == player_folded_boat.volume() );
CHECK( boat_item_weight == player_folded_boat.weight() );
// should succeed now avatar has hand_pump
optional_vpart_position ovp = m.veh_at( u.get_location() );
REQUIRE( ovp.has_value() );

// unfold the player folded one
u.assign_activity( player_activity( vehicle_unfolding_activity_actor( player_folded_boat ) ) );
while( !u.activity.is_null() ) {
u.set_moves( u.get_speed() );
u.activity.do_turn( u );
}
// set damage/degradation on every part
vehicle &veh = ovp->vehicle();
for( const vpart_reference &vpr : veh.get_all_parts() ) {
item base = vpr.part().get_base();
base.set_degradation( damage_preset.degradation * base.max_damage() );
base.set_damage( damage_preset.damage * base.max_damage() );
vpr.part().set_base( base );
veh.set_hp( vpr.part(), vpr.info().durability, true );
}

optional_vpart_position unfolded_boat_part = m.veh_at( u.get_location() );
REQUIRE( unfolded_boat_part.has_value() );
// fold into an item
complete_activity( u, vehicle_folding_activity_actor( veh ) );

// verify the damage/degradation roundtripped via serialization on every part
for( const vpart_reference &vpr : unfolded_boat_part->vehicle().get_all_parts() ) {
const item &base = vpr.part().get_base();
CHECK( base.damage() == ( expect_damage * base.max_damage() ) );
CHECK( base.degradation() == ( expect_degradation * base.max_damage() ) );
CHECK( vpr.part().health_percent() == expected_hp );
}
// should have no value as vehicle is now folded into item
REQUIRE( !m.veh_at( u.get_location() ).has_value() );

// copy the player-folded vehicle item and delete it from the map
map_stack map_items = m.i_at( u.pos_bub() );
REQUIRE( map_items.size() == 1 );
item player_folded_veh = map_items.only_item();
map_items.clear();

// check player-folded vehicle has same volume/weight as item factory one
// may be have some kind of approximation here for packaging/wrappings?
CHECK( factory_item_volume == player_folded_veh.volume() );
CHECK( factory_item_weight == player_folded_veh.weight() );

// unfold the player folded one
complete_activity( u, vehicle_unfolding_activity_actor( player_folded_veh ) );

optional_vpart_position ovp_unfolded = m.veh_at( u.get_location() );
REQUIRE( ovp_unfolded.has_value() );

// verify the damage/degradation roundtripped via serialization on every part
for( const vpart_reference &vpr : ovp_unfolded->vehicle().get_all_parts() ) {
const item &base = vpr.part().get_base();
CHECK( base.damage() == ( damage_preset.expect_damage * base.max_damage() ) );
CHECK( base.degradation() == ( damage_preset.expect_degradation * base.max_damage() ) );
CHECK( vpr.part().health_percent() == damage_preset.expect_hp );
}

m.destroy_vehicle( &ovp_unfolded->vehicle() );
}

// Testing iuse::unfold_generic and vehicle part degradation
TEST_CASE( "Unfolding vehicle parts and testing degradation", "[item][degradation][vehicle]" )
{
struct degradation_preset {
double damage;
double degradation;
double expect_damage;
double expect_degradation;
double expect_hp;
std::vector<vehicle_preset> vehicle_presets {
{ itype_folded_inflatable_boat, { itype_hand_pump } },
{ itype_folded_wheelchair_generic, { } },
{ itype_folded_bicycle, { } },
};

const std::vector<degradation_preset> presets {
const std::vector<damage_preset> presets {
{ 0.00, 0.00, 0.00, 0.00, 1.00 }, // 0% damaged, 0% degraded
{ 0.25, 0.25, 0.00, 0.25, 1.00 }, // 25% damaged, 25% degraded
{ 0.50, 0.50, 0.25, 0.50, 0.75 }, // 50% damaged, 50% degraded
Expand All @@ -235,7 +258,11 @@ TEST_CASE( "Unfolding vehicle parts and testing degradation", "[item][degradatio
{ 1.00, 1.00, 0.75, 1.00, 0.25 }, // 100% damaged, 100% degraded
};

for( const degradation_preset &p : presets ) {
unfold_and_check( p.damage, p.degradation, p.expect_damage, p.expect_degradation, p.expect_hp );
for( const vehicle_preset &veh_preset : vehicle_presets ) {
for( const damage_preset &damage_preset : presets ) {
unfold_and_check( veh_preset, damage_preset );
}
}

clear_vehicles( &get_map() );
}

0 comments on commit de51069

Please sign in to comment.