From 5ca1e02a055981cf2205e1431b4c0f1f194dda16 Mon Sep 17 00:00:00 2001 From: ehughsbaird <44244083+ehughsbaird@users.noreply.github.com> Date: Sat, 12 Oct 2024 18:47:53 +0000 Subject: [PATCH] Fix non-battery fueled items using charges Only test the energy remaining if the item uses energy, otherwise test the ammo, as before. Adds a regression test too. --- src/item.cpp | 22 ++++++++++++++++++++-- src/item.h | 2 ++ tests/active_item_test.cpp | 28 ++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index bbf0e03a6c0de..d73354dea1326 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -10858,8 +10858,25 @@ int item::ammo_remaining( const bool include_linked ) const return ammo_remaining( nullptr, include_linked ); } +bool item::uses_energy() const +{ + if( is_vehicle_battery() ) { + return true; + } + const item *mag = magazine_current(); + if( mag && mag->uses_energy() ) { + return true; + } + return has_flag( flag_USES_BIONIC_POWER ) || + has_flag( flag_USE_UPS ) || + ( is_magazine() && ammo_capacity( ammo_battery ) > 0 ); +} + units::energy item::energy_remaining( const Character *carrier ) const { + if( !uses_energy() ) { + return 0_kJ; + } units::energy ret = 0_kJ; // Future energy based batteries @@ -14103,8 +14120,9 @@ bool item::process_tool( Character *carrier, const tripoint &pos ) } // if insufficient available charges shutdown the tool - if( ( type->tool->turns_per_charge > 0 || type->tool->power_draw > 0_W ) && - energy_remaining( carrier ) < energy_per_second() ) { + if( ( type->tool->power_draw > 0_W || type->tool->turns_per_charge > 0 ) && + ( ( uses_energy() && energy_remaining( carrier ) < energy_per_second() ) || + ( !uses_energy() && ammo_remaining( carrier, true ) == 0 ) ) ) { if( carrier && has_flag( flag_USE_UPS ) ) { carrier->add_msg_if_player( m_info, _( "You need an UPS to run the %s!" ), tname() ); } diff --git a/src/item.h b/src/item.h index 5c00e39de5db0..44ee2659a2240 100644 --- a/src/item.h +++ b/src/item.h @@ -2442,6 +2442,8 @@ class item : public visitable */ int shots_remaining( const Character *carrier ) const; + // Does this use electrical energy, or is it fueled by something else? + bool uses_energy() const; /** * Energy available from battery/UPS/bionics * @param carrier is used for UPS and bionic power. diff --git a/tests/active_item_test.cpp b/tests/active_item_test.cpp index 36cdd9fff8923..94db77df1f7ad 100644 --- a/tests/active_item_test.cpp +++ b/tests/active_item_test.cpp @@ -44,6 +44,34 @@ TEST_CASE( "active_items_processed_regularly", "[active_item]" ) CHECK( here.i_at( player_character.pos_bub() ).only_item().typeId().str() == "chainsaw_off" ); } +TEST_CASE( "non_energy_tool_power_consumption_rate", "[active_item]" ) +{ + // Gasoline lantern without a battery, using gasoline instead + item test_lantern( "gasoline_lantern_on" ); + const itype_id &default_ammo = test_lantern.ammo_default(); + const int ammo_capacity = test_lantern.ammo_capacity( default_ammo->ammo->type ); + test_lantern.ammo_set( default_ammo, ammo_capacity ); + REQUIRE_FALSE( test_lantern.uses_energy() ); + + test_lantern.active = true; + + // Now process the tool until it runs out of fuel. + int seconds_active = 0; + map &here = get_map(); + // Must be captured before it's inactive and transforms + int turns_per_charge = test_lantern.type->tool->turns_per_charge; + REQUIRE( test_lantern.ammo_remaining() == ammo_capacity ); + do { + calendar::turn += 1_seconds; + test_lantern.process( here, nullptr, tripoint_zero ); + seconds_active++; + } while( test_lantern.active ); + REQUIRE( test_lantern.ammo_remaining() == 0 ); + // Runtime vaguely in the bounds we expect. + CHECK( seconds_active > ( turns_per_charge - 1 ) * ammo_capacity ); + CHECK( seconds_active < ( turns_per_charge + 1 ) * ammo_capacity ); +} + TEST_CASE( "tool_power_consumption_rate", "[active_item]" ) { // Give the flashlight a fully charged battery, 56 kJ