Skip to content

Commit

Permalink
Fix non-battery fueled items using charges
Browse files Browse the repository at this point in the history
Only test the energy remaining if the item uses energy, otherwise test
the ammo, as before.

Adds a regression test too.
  • Loading branch information
ehughsbaird committed Oct 12, 2024
1 parent b2e7940 commit 5ca1e02
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
22 changes: 20 additions & 2 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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() );
}
Expand Down
2 changes: 2 additions & 0 deletions src/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
28 changes: 28 additions & 0 deletions tests/active_item_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 5ca1e02

Please sign in to comment.