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

More Gun Mod Upgrades #54961

Merged
merged 3 commits into from
Jan 31, 2022
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
36 changes: 33 additions & 3 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,8 +575,8 @@ item &item::ammo_set( const itype_id &ammo, int qty )
qty = ammo_capacity( ammo_type );

// else try to add a magazine using default ammo count property if set
} else if( !magazine_default().is_null() ) {
item mag( magazine_default() );
} else if( !magazine_default( true ).is_null() ) {
item mag( magazine_default( true ) );
if( mag.type->magazine->count > 0 ) {
qty = mag.type->magazine->count;
} else {
Expand Down Expand Up @@ -9591,6 +9591,24 @@ skill_id item::melee_skill() const
return res;
}


int item::min_cycle_recoil() const
{
if( !is_gun() ) {
return 0;
}
int to_cycle = type->gun->min_cycle_recoil;
// This should only be used for one mod or it'll mess things up
// TODO: maybe generalize this so you can have mods for hot loads or whatever
for( const item *mod : gunmods() ) {
// this value defaults to -1
if( mod->type->gunmod->overwrite_min_cycle_recoil > 0 ) {
to_cycle = mod->type->gunmod->overwrite_min_cycle_recoil;
}
}
return to_cycle;
}

int item::gun_dispersion( bool with_ammo, bool with_scaling ) const
{
if( !is_gun() ) {
Expand Down Expand Up @@ -10108,8 +10126,20 @@ bool item::uses_magazine() const
return contents.has_pocket_type( item_pocket::pocket_type::MAGAZINE_WELL );
}

itype_id item::magazine_default( bool /* conversion */ ) const
itype_id item::magazine_default( bool conversion ) const
{
// consider modded ammo types
if( conversion && !ammo_types().empty() ) {
const itype_id ammo = ammo_default();
for( const itype_id mag : contents.magazine_compatible() ) {
auto mag_types = mag->magazine->type;
if( mag_types.find( ammo->ammo->type ) != mag_types.end() ) {
return mag;
}
}
}

// otherwise return the default
return contents.magazine_default();
}

Expand Down
6 changes: 5 additions & 1 deletion src/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -2244,7 +2244,7 @@ class item : public visitable
/** Get the default magazine type (if any) for the current effective ammo type
* @param conversion whether to include the effect of any flags or mods which convert item's ammo type
* @return magazine type or "null" if item has integral magazine or no magazines for current ammo type */
itype_id magazine_default( bool conversion = true ) const;
itype_id magazine_default( bool conversion = false ) const;

/** Get compatible magazines (if any) for this item
* @return magazine compatibility which is always empty if item has integral magazine
Expand Down Expand Up @@ -2344,6 +2344,10 @@ class item : public visitable
* Returns empty instance on non-gun items.
*/
damage_instance gun_damage( bool with_ammo = true, bool shot = false ) const;
/**
* The minimum force required to cycle the gun, can be overridden by mods
*/
int min_cycle_recoil() const;
/**
* Summed dispersion of a gun, including values from mods. Returns 0 on non-gun items.
*/
Expand Down
1 change: 1 addition & 0 deletions src/item_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2931,6 +2931,7 @@ void Item_factory::load( islot_gunmod &slot, const JsonObject &jo, const std::st
assign( jo, "ammo_to_fire_multiplier", slot.ammo_to_fire_multiplier );
assign( jo, "ammo_to_fire_modifier", slot.ammo_to_fire_modifier );
assign( jo, "weight_multiplier", slot.weight_multiplier );
assign( jo, "overwrite_min_cycle_recoil", slot.overwrite_min_cycle_recoil );
// convert aim_speed to FoV and aim_speed_modifier automatically, if FoV is not set
if( slot.aim_speed >= 0 && slot.field_of_view <= 0 ) {
if( slot.aim_speed > 6 ) {
Expand Down
3 changes: 3 additions & 0 deletions src/itype.h
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,9 @@ struct islot_gunmod : common_ranged_data {

/** Not compatable on weapons that have this mod slot */
std::set<gunmod_location> blacklist_mod;

// minimum recoil to cycle while this is installed
int overwrite_min_cycle_recoil = -1;
};

struct islot_magazine {
Expand Down
2 changes: 1 addition & 1 deletion src/ranged.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ bool Character::handle_gun_damage( item &it )
it.inc_damage();
}
if( !it.has_flag( flag_PRIMITIVE_RANGED_WEAPON ) ) {
if( it.ammo_data() != nullptr && ( ( it.ammo_data()->ammo->recoil < firing.min_cycle_recoil ) ||
if( it.ammo_data() != nullptr && ( ( it.ammo_data()->ammo->recoil < it.min_cycle_recoil() ) ||
( it.has_fault_flag( "BAD_CYCLING" ) && one_in( 16 ) ) ) &&
it.faults_potential().count( fault_gun_chamber_spent ) ) {
add_msg_player_or_npc( m_bad, _( "Your %s fails to cycle!" ),
Expand Down