Skip to content

Commit

Permalink
Fixing error thrown when unloading gun when there is no inventory ava…
Browse files Browse the repository at this point in the history
…ilable (CleverRaven#48999)

* Adding unloaded gun to avoid
* Added unit test
* Unload partial ammo of wielded item without duplication

Signed-off-by: Lance Finfrock <lancewf@gmail.com>
Co-authored-by: actual-nh <74678550+actual-nh@users.noreply.github.com>
Co-authored-by: RoyBerube <royberube1965@gmail.com>
  • Loading branch information
3 people authored and John-Candlebury committed May 30, 2021
1 parent b2cd487 commit d828013
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/activity_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1704,7 +1704,7 @@ void unload_activity_actor::unload( Character &who, item_location &target )
if( contained->ammo_type() == ammotype( "plutonium" ) ) {
contained->charges /= PLUTONIUM_CHARGES;
}
if( who.as_player()->add_or_drop_with_msg( *contained, true ) ) {
if( who.as_player()->add_or_drop_with_msg( *contained, true, &it ) ) {
qty += contained->charges;
remove_contained.push_back( contained );
actually_unloaded = true;
Expand Down
6 changes: 3 additions & 3 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3679,9 +3679,9 @@ units::mass Character::weight_capacity() const
return ret;
}

bool Character::can_pickVolume( const item &it, bool ) const
bool Character::can_pickVolume( const item &it, bool, const item *avoid ) const
{
if( weapon.can_contain( it ) ) {
if( weapon.can_contain( it ) && ( avoid == nullptr || &weapon != avoid ) ) {
return true;
}
for( const item &w : worn ) {
Expand Down Expand Up @@ -12820,7 +12820,7 @@ bool Character::add_or_drop_with_msg( item &it, const bool /*unloading*/, const
liquid_handler::consume_liquid( it, 1, avoid );
return it.charges <= 0;
}
if( !this->can_pickVolume( it ) ) {
if( !this->can_pickVolume( it, false, avoid ) ) {
put_into_vehicle_or_drop( *this, item_drop_reason::too_large, { it } );
} else if( !this->can_pickWeight( it, !get_option<bool>( "DANGEROUS_PICKUPS" ) ) ) {
put_into_vehicle_or_drop( *this, item_drop_reason::too_heavy, { it } );
Expand Down
2 changes: 1 addition & 1 deletion src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -1714,7 +1714,7 @@ class Character : public Creature, public visitable
bool fun_to_read( const item &book ) const;
int book_fun_for( const item &book, const Character &p ) const;

bool can_pickVolume( const item &it, bool safe = false ) const;
bool can_pickVolume( const item &it, bool safe = false, const item *avoid = nullptr ) const;
bool can_pickWeight( const item &it, bool safe = true ) const;
bool can_pickWeight_partial( const item &it, bool safe = true ) const;
/**
Expand Down
88 changes: 88 additions & 0 deletions tests/unload_naked_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <list>
#include <memory>

#include "avatar.h"
#include "calendar.h"
#include "catch/catch.hpp"
#include "item.h"
#include "map.h"
#include "map_helpers.h"
#include "optional.h"
#include "player_helpers.h"
#include "type_id.h"

/**
* When a player has no open inventory to place unloaded bullets, but there is room in the gun being
* unloaded the bullets are dropped.
* issue# 29839
*/

TEST_CASE( "unload_revolver_naked_one_bullet", "[unload][nonmagzine]" )
{
clear_avatar();
clear_map();

Character &dummy = get_player_character();
avatar &player_character = get_avatar();

// revolver with only one of six bullets
item revolver( "ruger_redhawk" );
revolver.ammo_set( revolver.ammo_default(), 1 );

// wield the revolver
REQUIRE( !player_character.is_armed( ) );
REQUIRE( player_character.wield( revolver ) );
REQUIRE( player_character.is_armed( ) );

CHECK( player_character.weapon.ammo_remaining() == 1 );

// Unload weapon
item_location revo_loc( dummy, &player_character.weapon );
player_character.moves = 100;
REQUIRE( player_character.unload( revo_loc ) );
player_character.activity.do_turn( player_character );

// No bullets in wielded gun
CHECK( player_character.weapon.ammo_remaining() == 0 );

// No bullets in inventory
const std::vector<item *> bullets = dummy.items_with( []( const item & item ) {
return item.is_ammo();
} );
CHECK( bullets.empty() );
}

TEST_CASE( "unload_revolver_naked_fully_loaded", "[unload][nonmagzine]" )
{
clear_avatar();
clear_map();

Character &dummy = get_player_character();
avatar &player_character = get_avatar();

// revolver fully loaded
item revolver( "ruger_redhawk" );
revolver.ammo_set( revolver.ammo_default(), revolver.remaining_ammo_capacity() );

// wield the revolver
REQUIRE( !player_character.is_armed( ) );
REQUIRE( player_character.wield( revolver ) );
REQUIRE( player_character.is_armed( ) );

CHECK( player_character.weapon.remaining_ammo_capacity() == 0 );

// Unload weapon
item_location revo_loc( dummy, &player_character.weapon );
player_character.moves = 100;
REQUIRE( player_character.unload( revo_loc ) );
player_character.activity.do_turn( player_character );

// No bullets in wielded gun
CHECK( player_character.weapon.ammo_remaining() == 0 );

// No bullets in inventory
const std::vector<item *> bullets = dummy.items_with( []( const item & item ) {
return item.is_ammo();
} );
CHECK( bullets.empty() );
}

0 comments on commit d828013

Please sign in to comment.