Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not to try to reload a gun without default ammo type defined #73714

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/character_ammo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,14 @@ bool Character::list_ammo( const item_location &base, std::vector<item::reload_o
int ammo_search_range = is_mounted() ? -1 : 1;
for( item_location &p : opts ) {
for( item_location &ammo : find_ammo( *p, empty, ammo_search_range ) ) {
if( p->can_reload_with( *ammo.get_item(), false ) ) {
if( p.can_reload_with( ammo, false ) ) {
// Record that there's a matching ammo type,
// even if something is preventing reloading at the moment.
ammo_match_found = true;
} else if( ( ammo->has_flag( flag_SPEEDLOADER ) || ammo->has_flag( flag_SPEEDLOADER_CLIP ) ) &&
p->allows_speedloader( ammo->typeId() ) && ammo->ammo_remaining() > 1 && p->ammo_remaining() < 1 ) {
// Again, this is "are they compatible", later check handles "can we do it now".
ammo_match_found = p->can_reload_with( *ammo.get_item(), false );
ammo_match_found = p.can_reload_with( ammo, false );
}
if( can_reload( *p, ammo.get_item() ) ) {
ammo_list.emplace_back( this, p, std::move( ammo ) );
Expand Down
2 changes: 1 addition & 1 deletion src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9998,7 +9998,7 @@ static item::reload_option favorite_ammo_or_select( avatar &u, item_location &lo
std::vector<item::reload_option> ammo_list;
if( u.list_ammo( loc, ammo_list, false ) ) {
const auto is_favorite_and_compatible = [&loc, &u]( const item::reload_option & opt ) {
return opt.ammo == u.ammo_location && loc->can_reload_with( *u.ammo_location.get_item(), false );
return opt.ammo == u.ammo_location && loc.can_reload_with( u.ammo_location, false );
};
auto it = std::find_if( ammo_list.begin(), ammo_list.end(), is_favorite_and_compatible );
if( it != ammo_list.end() ) {
Expand Down
8 changes: 4 additions & 4 deletions src/game_inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2803,7 +2803,7 @@ class select_ammo_inventory_preset : public inventory_selector_preset

append_cell( [&you, target]( const item_location & loc ) {
for( const item_location &opt : get_possible_reload_targets( target ) ) {
if( opt->can_reload_with( *loc, true ) ) {
if( opt.can_reload_with( loc, true ) ) {
if( opt == target ) {
return std::string();
}
Expand Down Expand Up @@ -2871,11 +2871,11 @@ class select_ammo_inventory_preset : public inventory_selector_preset

for( item_location &p : opts ) {
if( ( loc->has_flag( flag_SPEEDLOADER ) && p->allows_speedloader( loc->typeId() ) &&
loc->ammo_remaining() > 1 && p->ammo_remaining() < 1 ) && p->can_reload_with( *loc, true ) ) {
loc->ammo_remaining() > 1 && p->ammo_remaining() < 1 ) && p.can_reload_with( loc, true ) ) {
return true;
}

if( p->can_reload_with( *loc, true ) ) {
if( p.can_reload_with( loc, true ) ) {
return true;
}
}
Expand Down Expand Up @@ -2944,7 +2944,7 @@ item::reload_option game_menus::inv::select_ammo( Character &you, const item_loc

item_location target_loc;
for( const item_location &opt : get_possible_reload_targets( loc ) ) {
if( opt->can_reload_with( *selected.first, true ) ) {
if( opt.can_reload_with( selected.first, true ) ) {
target_loc = opt;
break;
}
Expand Down
4 changes: 2 additions & 2 deletions src/inventory_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3381,7 +3381,7 @@ void ammo_inventory_selector::set_all_entries_chosen_count()
for( inventory_entry *entry : col->get_entries( return_item, true ) ) {
for( const item_location &loc : get_possible_reload_targets( reload_loc ) ) {
item_location it = entry->any_item();
if( loc->can_reload_with( *it, true ) ) {
if( loc.can_reload_with( it, true ) ) {
item::reload_option tmp_opt( &u, loc, it );
int count = entry->get_available_count();
if( it->has_flag( flag_SPEEDLOADER ) || it->has_flag( flag_SPEEDLOADER_CLIP ) ) {
Expand All @@ -3402,7 +3402,7 @@ void ammo_inventory_selector::mod_chosen_count( inventory_entry &entry, int valu
return;
}
for( const item_location &loc : get_possible_reload_targets( reload_loc ) ) {
if( loc->can_reload_with( *entry.any_item(), true ) ) {
if( loc.can_reload_with( entry.any_item(), true ) ) {
item::reload_option tmp_opt( &u, loc, entry.any_item() );
tmp_opt.qty( entry.chosen_count + value );
entry.chosen_count = tmp_opt.qty();
Expand Down
14 changes: 14 additions & 0 deletions src/item_location.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1157,3 +1157,17 @@ std::unique_ptr<talker> get_talker_for( item_location *it )
return std::make_unique<talker_item>( it );
}

bool item_location::can_reload_with( const item_location &ammo, bool now ) const
{
const item_location reloadable = *this;
if( reloadable->is_gun() && !reloadable->ammo_default() ) {
return false;
} else if( reloadable->is_magazine() ) {
if( reloadable.has_parent() ) {
if( reloadable.parent_item()->is_gun() && !reloadable.parent_item()->ammo_default() ) {
return false;
}
}
}
return reloadable->can_reload_with( *ammo, now );
}
7 changes: 7 additions & 0 deletions src/item_location.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ class item_location
*/
void overflow();

/**
* returns whether the item can be reloaded with the specified item.
* @param ammo item to be loaded in
* @param now whether the currently contained ammo/magazine should be taken into account
*/
bool can_reload_with( const item_location &ammo, bool now ) const;

private:
class impl;

Expand Down
4 changes: 2 additions & 2 deletions tests/player_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,15 +180,15 @@ void arm_shooter( Character &shooter, const std::string &gun_type,
if( gun->magazine_integral() ) {
item_location ammo = shooter.i_add( item( ammo_id, calendar::turn,
gun->ammo_capacity( type_of_ammo ) ) );
REQUIRE( gun->can_reload_with( *ammo, true ) );
REQUIRE( gun.can_reload_with( ammo, true ) );
REQUIRE( shooter.can_reload( *gun, &*ammo ) );
gun->reload( shooter, ammo, gun->ammo_capacity( type_of_ammo ) );
} else {
const itype_id magazine_id = gun->magazine_default();
item_location magazine = shooter.i_add( item( magazine_id ) );
item_location ammo = shooter.i_add( item( ammo_id, calendar::turn,
magazine->ammo_capacity( type_of_ammo ) ) );
REQUIRE( magazine->can_reload_with( *ammo, true ) );
REQUIRE( magazine.can_reload_with( ammo, true ) );
REQUIRE( shooter.can_reload( *magazine, &*ammo ) );
magazine->reload( shooter, ammo, magazine->ammo_capacity( type_of_ammo ) );
gun->reload( shooter, magazine, magazine->ammo_capacity( type_of_ammo ) );
Expand Down
4 changes: 2 additions & 2 deletions tests/reloading_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ TEST_CASE( "automatic_reloading_action", "[reload],[gun]" )

dummy.set_wielded_item( item( "sw_610", calendar::turn_zero, 0 ) );
REQUIRE( dummy.get_wielded_item()->ammo_remaining() == 0 );
REQUIRE( dummy.get_wielded_item()->can_reload_with( *ammo, false ) );
REQUIRE( dummy.get_wielded_item().can_reload_with( ammo, false ) );

WHEN( "the player triggers auto reload until the revolver is full" ) {
reload_a_revolver( dummy, *dummy.get_wielded_item(), *ammo );
Expand All @@ -937,7 +937,7 @@ TEST_CASE( "automatic_reloading_action", "[reload],[gun]" )
GIVEN( "the player has another gun with ammo" ) {
item_location gun2 = dummy.i_add( item( "sw_610", calendar::turn_zero, 0 ) );
REQUIRE( gun2->ammo_remaining() == 0 );
REQUIRE( gun2->can_reload_with( *ammo, false ) );
REQUIRE( gun2.can_reload_with( ammo, false ) );
WHEN( "the player triggers auto reload until the first revolver is full" ) {
reload_a_revolver( dummy, *dummy.get_wielded_item(), *ammo );
WHEN( "the player triggers auto reload until the second revolver is full" ) {
Expand Down
Loading