From 06922659220af602c302d7ea450a55a76de19926 Mon Sep 17 00:00:00 2001 From: Hirmuolio Date: Thu, 8 Oct 2020 02:46:36 +0300 Subject: [PATCH] simplify item::damage_level() (#44563) --- src/activity_handlers.cpp | 8 ++++---- src/character.cpp | 2 +- src/crafting.cpp | 2 +- src/game.cpp | 2 +- src/inventory.cpp | 2 +- src/item.cpp | 36 ++++++++++++++++++------------------ src/item.h | 6 ++---- src/iuse.cpp | 10 +++++----- src/iuse_actor.cpp | 6 +++--- src/iuse_actor.h | 2 +- src/monattack.cpp | 4 ++-- src/monster.cpp | 6 +++--- src/player.cpp | 2 +- src/veh_interact.cpp | 2 +- src/veh_utils.cpp | 4 ++-- src/vehicle.h | 2 +- src/vehicle_part.cpp | 6 +++--- tests/item_tname_test.cpp | 10 +++++----- 18 files changed, 55 insertions(+), 57 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 5b7a479f415d8..6cf47d447eb49 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -873,11 +873,11 @@ static void butchery_drops_harvest( item *corpse_item, const mtype &mt, player & // mass_ratio will override the use of base_num, scale_num, and max if( entry.mass_ratio != 0.00f ) { roll = static_cast( std::round( entry.mass_ratio * monster_weight ) ); - roll = corpse_damage_effect( roll, entry.type, corpse_item->damage_level( 4 ) ); + roll = corpse_damage_effect( roll, entry.type, corpse_item->damage_level() ); } else if( entry.type != "bionic" && entry.type != "bionic_group" ) { roll = std::min( entry.max, std::round( rng_float( min_num, max_num ) ) ); // will not give less than min_num defined in the JSON - roll = std::max( corpse_damage_effect( roll, entry.type, corpse_item->damage_level( 4 ) ), + roll = std::max( corpse_damage_effect( roll, entry.type, corpse_item->damage_level() ), entry.base_num.first ); } itype_id drop_id = itype_id::NULL_ID(); @@ -929,10 +929,10 @@ static void butchery_drops_harvest( item *corpse_item, const mtype &mt, player & } } if( action == butcher_type::DISSECT ) { - int roll = roll_butchery() - corpse_item->damage_level( 4 ); + int roll = roll_butchery() - corpse_item->damage_level(); roll = roll < 0 ? 0 : roll; roll = std::min( entry.max, roll ); - add_msg_debug( _( "Roll penalty for corpse damage = %s" ), 0 - corpse_item->damage_level( 4 ) ); + add_msg_debug( _( "Roll penalty for corpse damage = %s" ), 0 - corpse_item->damage_level() ); if( entry.type == "bionic" ) { butcher_cbm_item( drop_id, p.pos(), calendar::turn, roll, entry.flags, entry.faults ); } else if( entry.type == "bionic_group" ) { diff --git a/src/character.cpp b/src/character.cpp index e489ff7e46b2c..d73fdc4a7e516 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -9406,7 +9406,7 @@ bool Character::armor_absorb( damage_unit &du, item &armor, const bodypart_id &b material.cut_dmg_verb(); const std::string pre_damage_name = armor.tname(); - const std::string pre_damage_adj = armor.get_base_material().dmg_adj( armor.damage_level( 4 ) ); + const std::string pre_damage_adj = armor.get_base_material().dmg_adj( armor.damage_level() ); // add "further" if the damage adjective and verb are the same std::string format_string = ( pre_damage_adj == damage_verb ) ? diff --git a/src/crafting.cpp b/src/crafting.cpp index b2428a8b8532c..9d701b8f0c738 100644 --- a/src/crafting.cpp +++ b/src/crafting.cpp @@ -2239,7 +2239,7 @@ void Character::complete_disassemble( item_location &target, const recipe &dis ) // has been removed. item dis_item = org_item; - float component_success_chance = std::min( std::pow( 0.8, dis_item.damage_level( 4 ) ), 1.0 ); + float component_success_chance = std::min( std::pow( 0.8, dis_item.damage_level() ), 1.0 ); add_msg( _( "You disassemble the %s into its components." ), dis_item.tname() ); // Remove any batteries, ammo and mods first diff --git a/src/game.cpp b/src/game.cpp index 7f15622b1c5b1..53f8ea1966e1d 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -5330,7 +5330,7 @@ bool game::revive_corpse( const tripoint &p, item &it ) void game::save_cyborg( item *cyborg, const tripoint &couch_pos, player &installer ) { int damage = cyborg->damage(); - int dmg_lvl = cyborg->damage_level( 4 ); + int dmg_lvl = cyborg->damage_level(); int difficulty = 12; if( damage != 0 ) { diff --git a/src/inventory.cpp b/src/inventory.cpp index b7342506a526c..c06fde710afad 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -824,7 +824,7 @@ int inventory::leak_level( const std::string &flag ) const if( elem_stack_iter.has_flag( flag_LEAK_ALWAYS ) ) { ret += elem_stack_iter.volume() / units::legacy_volume_factor; } else if( elem_stack_iter.has_flag( flag_LEAK_DAM ) && elem_stack_iter.damage() > 0 ) { - ret += elem_stack_iter.damage_level( 4 ); + ret += elem_stack_iter.damage_level(); } } } diff --git a/src/item.cpp b/src/item.cpp index f7aab5d9f3a45..3e7c8410729cc 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -723,16 +723,16 @@ int item::damage() const return damage_; } -int item::damage_level( int max ) const +int item::damage_level() const { - if( damage_ == 0 || max <= 0 ) { + if( damage_ == 0 ) { return 0; } else if( max_damage() <= 1 ) { - return damage_ > 0 ? max : damage_; + return damage_ > 0 ? 4 : damage_; } else if( damage_ < 0 ) { - return -( ( max - 1 ) * ( -damage_ - 1 ) / ( max_damage() - 1 ) + 1 ); + return -( 3 * ( -damage_ - 1 ) / ( max_damage() - 1 ) + 1 ); } else { - return ( max - 1 ) * ( damage_ - 1 ) / ( max_damage() - 1 ) + 1; + return 3 * ( damage_ - 1 ) / ( max_damage() - 1 ) + 1; } } @@ -4939,7 +4939,7 @@ int item::price( bool practical ) const int child = units::to_cent( practical ? e->type->price_post : e->type->price ); if( e->damage() > 0 ) { // maximal damage level is 4, maximal reduction is 40% of the value. - child -= child * static_cast( e->damage_level( 4 ) ) / 10; + child -= child * static_cast( e->damage_level() ) / 10; } if( e->count_by_charges() || e->made_of( phase_id::LIQUID ) ) { @@ -5235,7 +5235,7 @@ int item::damage_melee( damage_type dt ) const // effectiveness is reduced by 10% per damage level int res = type->melee[ static_cast( dt )]; - res -= res * damage_level( 4 ) * 0.1; + res -= res * damage_level() * 0.1; // apply type specific flags switch( dt ) { @@ -6023,8 +6023,8 @@ bool item::ready_to_revive( const tripoint &pos ) const } int age_in_hours = to_hours( age() ); age_in_hours -= static_cast( static_cast( burnt ) / ( volume() / 250_ml ) ); - if( damage_level( 4 ) > 0 ) { - age_in_hours /= ( damage_level( 4 ) + 1 ); + if( damage_level() > 0 ) { + age_in_hours /= ( damage_level() + 1 ); } int rez_factor = 48 - age_in_hours; if( age_in_hours > 6 && ( rez_factor <= 0 || one_in( rez_factor ) ) ) { @@ -6099,7 +6099,7 @@ int item::bash_resist( bool to_self ) const // base resistance // Don't give reinforced items +armor, just more resistance to ripping - const int dmg = damage_level( 4 ); + const int dmg = damage_level(); const int eff_damage = to_self ? std::min( dmg, 0 ) : std::max( dmg, 0 ); const int eff_thickness = std::max( 1, get_thickness() - eff_damage ); @@ -6127,7 +6127,7 @@ int item::cut_resist( bool to_self ) const // base resistance // Don't give reinforced items +armor, just more resistance to ripping - const int dmg = damage_level( 4 ); + const int dmg = damage_level(); const int eff_damage = to_self ? std::min( dmg, 0 ) : std::max( dmg, 0 ); const int eff_thickness = std::max( 1, base_thickness - eff_damage ); @@ -6165,7 +6165,7 @@ int item::bullet_resist( bool to_self ) const // base resistance // Don't give reinforced items +armor, just more resistance to ripping - const int dmg = damage_level( 4 ); + const int dmg = damage_level(); const int eff_damage = to_self ? std::min( dmg, 0 ) : std::max( dmg, 0 ); const int eff_thickness = std::max( 1, base_thickness - eff_damage ); @@ -6320,7 +6320,7 @@ bool item::inc_damage() nc_color item::damage_color() const { // TODO: unify with veh_interact::countDurability - switch( damage_level( 4 ) ) { + switch( damage_level() ) { default: // reinforced if( damage() <= min_damage() ) { @@ -6348,7 +6348,7 @@ nc_color item::damage_color() const std::string item::damage_symbol() const { - switch( damage_level( 4 ) ) { + switch( damage_level() ) { default: // reinforced return _( R"(++)" ); @@ -6384,7 +6384,7 @@ std::string item::durability_indicator( bool include_intact ) const } } else if( has_flag( flag_CORPSE ) ) { if( damage() > 0 ) { - switch( damage_level( 4 ) ) { + switch( damage_level() ) { case 1: outputstring = pgettext( "damage adjective", "bruised " ); break; @@ -6402,7 +6402,7 @@ std::string item::durability_indicator( bool include_intact ) const } else if( get_option( "ITEM_HEALTH_BAR" ) ) { outputstring = colorize( damage_symbol() + "\u00A0", damage_color() ); } else { - outputstring = string_format( "%s ", get_base_material().dmg_adj( damage_level( 4 ) ) ); + outputstring = string_format( "%s ", get_base_material().dmg_adj( damage_level() ) ); if( include_intact && outputstring == " " ) { outputstring = _( "fully intact " ); } @@ -7311,7 +7311,7 @@ int item::gun_dispersion( bool with_ammo, bool with_scaling ) const dispersion_sum += mod->type->gunmod->dispersion; } int dispPerDamage = get_option< int >( "DISPERSION_PER_GUN_DAMAGE" ); - dispersion_sum += damage_level( 4 ) * dispPerDamage; + dispersion_sum += damage_level() * dispPerDamage; dispersion_sum = std::max( dispersion_sum, 0 ); if( with_ammo && ammo_data() ) { dispersion_sum += ammo_data()->ammo->dispersion; @@ -7363,7 +7363,7 @@ damage_instance item::gun_damage( bool with_ammo ) const ret.add( ammo_data()->ammo->damage ); } - int item_damage = damage_level( 4 ); + int item_damage = damage_level(); if( item_damage > 0 ) { // TODO: This isn't a good solution for multi-damage guns/ammos for( damage_unit &du : ret ) { diff --git a/src/item.h b/src/item.h index 5d405de395091..4466e2af30055 100644 --- a/src/item.h +++ b/src/item.h @@ -1049,7 +1049,7 @@ class item : public visitable * here mostly for back-compatibility. It should not be used when * doing continuous math with the damage value: use damage() instead. * - * For example, for max = 4, min_damage = -1000, max_damage = 4000 + * For example, for min_damage = -1000, max_damage = 4000 * damage level * -1000 ~ -1 -1 * 0 0 @@ -1057,10 +1057,8 @@ class item : public visitable * 1334 ~ 2666 2 * 2667 ~ 3999 3 * 4000 4 - * - * @param max Maximum number of levels */ - int damage_level( int max ) const; + int damage_level() const; /** Minimum amount of damage to an item (state of maximum repair) */ int min_damage() const; diff --git a/src/iuse.cpp b/src/iuse.cpp index dec62594772b1..2d8664d8ac23c 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -3194,7 +3194,7 @@ int iuse::chainsaw_off( player *p, item *it, bool, const tripoint & ) { return toolweapon_off( *p, *it, false, - rng( 0, 10 ) - it->damage_level( 4 ) > 5 && !p->is_underwater(), + rng( 0, 10 ) - it->damage_level() > 5 && !p->is_underwater(), 20, _( "With a roar, the chainsaw leaps to life!" ), _( "You yank the cord, but nothing happens." ) ); } @@ -3203,7 +3203,7 @@ int iuse::elec_chainsaw_off( player *p, item *it, bool, const tripoint & ) { return toolweapon_off( *p, *it, false, - rng( 0, 10 ) - it->damage_level( 4 ) > 5 && !p->is_underwater(), + rng( 0, 10 ) - it->damage_level() > 5 && !p->is_underwater(), 20, _( "With a roar, the electric chainsaw leaps to life!" ), _( "You flip the switch, but nothing happens." ) ); } @@ -3212,7 +3212,7 @@ int iuse::cs_lajatang_off( player *p, item *it, bool, const tripoint & ) { return toolweapon_off( *p, *it, false, - rng( 0, 10 ) - it->damage_level( 4 ) > 5 && it->ammo_remaining() > 1 && !p->is_underwater(), + rng( 0, 10 ) - it->damage_level() > 5 && it->ammo_remaining() > 1 && !p->is_underwater(), 40, _( "With a roar, the chainsaws leap to life!" ), _( "You yank the cords, but nothing happens." ) ); } @@ -3221,7 +3221,7 @@ int iuse::ecs_lajatang_off( player *p, item *it, bool, const tripoint & ) { return toolweapon_off( *p, *it, false, - rng( 0, 10 ) - it->damage_level( 4 ) > 5 && it->ammo_remaining() > 1 && !p->is_underwater(), + rng( 0, 10 ) - it->damage_level() > 5 && it->ammo_remaining() > 1 && !p->is_underwater(), 40, _( "With a buzz, the chainsaws leap to life!" ), _( "You flip the on switch, but nothing happens." ) ); } @@ -3239,7 +3239,7 @@ int iuse::trimmer_off( player *p, item *it, bool, const tripoint & ) { return toolweapon_off( *p, *it, false, - rng( 0, 10 ) - it->damage_level( 4 ) > 3, + rng( 0, 10 ) - it->damage_level() > 3, 15, _( "With a roar, the hedge trimmer leaps to life!" ), _( "You yank the cord, but nothing happens." ) ); } diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 60e2361208668..3afd368245537 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -1480,7 +1480,7 @@ int salvage_actor::cut_up( player &p, item &it, item_location &cut ) const // chance of losing more components if the item is damaged. // If the item being cut is not damaged, no additional losses will be incurred. if( count > 0 && cut.get_item()->damage() > 0 ) { - float component_success_chance = std::min( std::pow( 0.8, cut.get_item()->damage_level( 4 ) ), + float component_success_chance = std::min( std::pow( 0.8, cut.get_item()->damage_level() ), 1.0 ); for( int i = count; i > 0; i-- ) { if( component_success_chance < rng_float( 0, 1 ) ) { @@ -1837,7 +1837,7 @@ int fireweapon_off_actor::use( player &p, item &it, bool t, const tripoint & ) c } p.moves -= moves; - if( rng( 0, 10 ) - it.damage_level( 4 ) > success_chance && !p.is_underwater() ) { + if( rng( 0, 10 ) - it.damage_level() > success_chance && !p.is_underwater() ) { if( noise > 0 ) { sounds::sound( p.pos(), noise, sounds::sound_t::combat, success_message ); } else { @@ -2771,7 +2771,7 @@ std::pair repair_item_actor::repair_chance( int action_difficulty = 0; switch( action_type ) { case RT_REPAIR: - action_difficulty = fix.damage_level( 4 ); + action_difficulty = fix.damage_level(); break; case RT_REFIT: // Let's make refitting as hard as recovering an almost-wrecked item diff --git a/src/iuse_actor.h b/src/iuse_actor.h index a3801b3a1ef6b..a16682d451e5c 100644 --- a/src/iuse_actor.h +++ b/src/iuse_actor.h @@ -600,7 +600,7 @@ class fireweapon_off_actor : public iuse_actor translation failure_message = to_translation( "hsss" ); // Due to bad roll int noise = 0; // If > 0 success message is a success sound instead int moves = 0; - // Lower is better: rng(0, 10) - item.damage_level( 4 ) > this variable + // Lower is better: rng(0, 10) - item.damage_level() > this variable int success_chance = INT_MIN; fireweapon_off_actor() : iuse_actor( "fireweapon_off" ) {} diff --git a/src/monattack.cpp b/src/monattack.cpp index 6303dc125ed7b..0bd46ab6b8765 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -994,7 +994,7 @@ bool mattack::resurrect( monster *z ) } return false; } - int raise_score = ( i.damage_level( 4 ) + 1 ) * mt->hp + i.burnt; + int raise_score = ( i.damage_level() + 1 ) * mt->hp + i.burnt; lowest_raise_score = std::min( lowest_raise_score, raise_score ); if( raise_score <= raising_level ) { corpses.push_back( std::make_pair( p, &i ) ); @@ -1048,7 +1048,7 @@ bool mattack::resurrect( monster *z ) // To appease static analysis cata_assert( raised.second ); // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) - float corpse_damage = raised.second->damage_level( 4 ); + float corpse_damage = raised.second->damage_level(); // Did we successfully raise something? if( g->revive_corpse( raised.first, *raised.second ) ) { here.i_rem( raised.first, raised.second ); diff --git a/src/monster.cpp b/src/monster.cpp index 89bf9a4009e7e..5b0395e32f3ef 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -2733,9 +2733,9 @@ void monster::init_from_item( const item &itm ) set_speed_base( get_speed_base() * 0.8 ); const int burnt_penalty = itm.burnt; hp = static_cast( hp * 0.7 ); - if( itm.damage_level( 4 ) > 0 ) { - set_speed_base( speed_base / ( itm.damage_level( 4 ) + 1 ) ); - hp /= itm.damage_level( 4 ) + 1; + if( itm.damage_level() > 0 ) { + set_speed_base( speed_base / ( itm.damage_level() + 1 ) ); + hp /= itm.damage_level() + 1; } hp -= burnt_penalty; diff --git a/src/player.cpp b/src/player.cpp index cfbca279c54a0..7e25c39d8d7c4 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -2716,7 +2716,7 @@ std::pair player::gunmod_installation_odds( const item &gun, const ite roll += ( get_dex() - 12 ) * 2; roll += ( get_int() - 12 ) * 2; // each level of damage to the base gun reduces success by 10% - roll -= std::max( gun.damage_level( 4 ), 0 ) * 10; + roll -= std::max( gun.damage_level(), 0 ) * 10; roll = std::min( std::max( roll, 0 ), 100 ); // risk of causing damage on failure increases with less durable guns diff --git a/src/veh_interact.cpp b/src/veh_interact.cpp index a1f1ae4ba08a1..0246779c0f106 100644 --- a/src/veh_interact.cpp +++ b/src/veh_interact.cpp @@ -1265,7 +1265,7 @@ void veh_interact::do_repair() ok = false; } } else { - ok = format_reqs( nmsg, vp.repair_requirements() * pt.base.damage_level( 4 ), vp.repair_skills, + ok = format_reqs( nmsg, vp.repair_requirements() * pt.base.damage_level(), vp.repair_skills, vp.repair_time( player_character ) * pt.base.damage() / pt.base.max_damage() ); } } diff --git a/src/veh_utils.cpp b/src/veh_utils.cpp index 8aa564f211520..f891e8c525cb9 100644 --- a/src/veh_utils.cpp +++ b/src/veh_utils.cpp @@ -76,7 +76,7 @@ vehicle_part &most_repairable_part( vehicle &veh, Character &who, bool only_repa } if( info.is_repairable() && - ( info.repair_requirements() * vpr.part().damage_level( 4 ) ).can_make_with_inventory( inv, + ( info.repair_requirements() * vpr.part().damage_level() ).can_make_with_inventory( inv, is_crafting_component ) ) { repairable_cache[ &vpr.part()] = repairable_status::repairable; } @@ -114,7 +114,7 @@ bool repair_part( vehicle &veh, vehicle_part &pt, Character &who_c ) // TODO: Expose base part damage somewhere, don't recalculate it here const requirement_data reqs = pt.is_broken() ? vp.install_requirements() : - vp.repair_requirements() * pt.damage_level( 4 ); + vp.repair_requirements() * pt.damage_level(); const inventory &inv = who.crafting_inventory( who.pos(), PICKUP_RANGE, !who.is_npc() ); inventory map_inv; diff --git a/src/vehicle.h b/src/vehicle.h index ffb622738043f..9a10fc14fe62b 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -400,7 +400,7 @@ struct vehicle_part { int max_damage() const; /** Current part damage level in same units as item::damage_level */ - int damage_level( int max ) const; + int damage_level() const; /** Current part damage as a percentage of maximum, with 0.0 being perfect condition */ double damage_percent() const; diff --git a/src/vehicle_part.cpp b/src/vehicle_part.cpp index 686f4888d3a84..db4b6f9a299e0 100644 --- a/src/vehicle_part.cpp +++ b/src/vehicle_part.cpp @@ -92,7 +92,7 @@ item vehicle_part::properties_to_item() const // force rationalization of damage values to the middle value of each damage level so // that parts will stack nicely - tmp.set_damage( tmp.damage_level( 4 ) * itype::damage_scale ); + tmp.set_damage( tmp.damage_level() * itype::damage_scale ); return tmp; } @@ -145,9 +145,9 @@ int vehicle_part::max_damage() const return base.max_damage(); } -int vehicle_part::damage_level( int max ) const +int vehicle_part::damage_level() const { - return base.damage_level( max ); + return base.damage_level(); } double vehicle_part::health_percent() const diff --git a/tests/item_tname_test.cpp b/tests/item_tname_test.cpp index c55bfb9561411..00ca6d332ab07 100644 --- a/tests/item_tname_test.cpp +++ b/tests/item_tname_test.cpp @@ -315,7 +315,7 @@ TEST_CASE( "item health or damage bar", "[item][tname][health][damage]" ) WHEN( "it is undamaged" ) { shirt.set_damage( 0 ); REQUIRE( shirt.damage() == 0 ); - REQUIRE( shirt.damage_level( 4 ) == 0 ); + REQUIRE( shirt.damage_level() == 0 ); // green `||` THEN( "it appears undamaged" ) { @@ -326,7 +326,7 @@ TEST_CASE( "item health or damage bar", "[item][tname][health][damage]" ) WHEN( "is is one-quarter damaged" ) { shirt.set_damage( dam25 ); REQUIRE( shirt.damage() == dam25 ); - REQUIRE( shirt.damage_level( 4 ) == 1 ); + REQUIRE( shirt.damage_level() == 1 ); // yellow `|\` THEN( "it appears slightly damaged" ) { @@ -337,7 +337,7 @@ TEST_CASE( "item health or damage bar", "[item][tname][health][damage]" ) WHEN( "it is half damaged" ) { shirt.set_damage( dam25 * 2 ); REQUIRE( shirt.damage() == dam25 * 2 ); - REQUIRE( shirt.damage_level( 4 ) == 2 ); + REQUIRE( shirt.damage_level() == 2 ); // magenta `|.` THEN( "it appears moderately damaged" ) { @@ -348,7 +348,7 @@ TEST_CASE( "item health or damage bar", "[item][tname][health][damage]" ) WHEN( "it is three-quarters damaged" ) { shirt.set_damage( dam25 * 3 ); REQUIRE( shirt.damage() == dam25 * 3 ); - REQUIRE( shirt.damage_level( 4 ) == 3 ); + REQUIRE( shirt.damage_level() == 3 ); // red `\.` THEN( "it appears heavily damaged" ) { @@ -359,7 +359,7 @@ TEST_CASE( "item health or damage bar", "[item][tname][health][damage]" ) WHEN( "it is totally damaged" ) { shirt.set_damage( dam25 * 4 ); REQUIRE( shirt.damage() == dam25 * 4 ); - REQUIRE( shirt.damage_level( 4 ) == 4 ); + REQUIRE( shirt.damage_level() == 4 ); // dark gray `XX` THEN( "it appears almost destroyed" ) {