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

Add gun-mounted ammo holders #70858

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 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
5 changes: 5 additions & 0 deletions data/json/flags.json
Original file line number Diff line number Diff line change
Expand Up @@ -2387,5 +2387,10 @@
"id": "BLEEDSLOW2",
"type": "json_flag",
"info": "The character bleeds even slower than normal, losing blood at 1/3rd the normal rate."
},
{
"id": "NOT_MAGAZINE",
"type": "json_flag",
"//": "Skips a check in Character::list_ammo that would otherwise prevent items here from being used to reload a gun."
}
]
28 changes: 28 additions & 0 deletions data/json/items/gunmod/accessories.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,33 @@
"location": "belt clip",
"mod_targets": [ "rugerlcp", "kp32", "kp3at", "kpf9", "cop_38", "moss_brownie" ],
"flags": [ "IS_ARMOR", "SKINTIGHT", "WATER_FRIENDLY" ]
},
{
"id": "12_gauge_shell_holder",
"type": "GUNMOD",
"name": { "str": "12 gauge shell holder" },
"description": "Designed to be affixed to the side of a shotgun's receiver, this polymer shotshell holder can store six 12 gauge shells for easy reloading.",
"weight": "16 g",
"volume": "60 ml",
"price": 2000,
"price_postapoc": 50,
"install_time": "30 s",
"material": [ "plastic" ],
"flags": [ "NOT_MAGAZINE", "TARDIS" ],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need TARDIS flag, a magazine well that covers the volume of the shotshell that isn't poking out should suffice 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, either the pocket is rigid and takes up the full space even without contents or it's not rigid and every loaded shell increases the size accordingly. From the images I'd expect the latter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't. I had it on there while trying to figure out a way to keep the shells from falling out when a full holder was removed, but it didn't work and I haven't gotten around to fixing it. Note that this PR is marked draft and is not ready for review.

"symbol": ":",
"color": "black",
"location": "loading port",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"location": "loading port",
"location": "rail",

Stock-mounted versions also exist https://www.midwayusa.com/product/1014560565?pid=668092
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the rail on the top of the gun? It wouldn't go up there.

Stock mounted versions are planned. This is a draft.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "rail" rail is on the side. It's where non-underbarrel laser sights go. (There are also underbarrel and top rails, which are referred to in-game as "underbarrel" and "sights" locations.)

On pump-action (and modern automatic) shotguns, the side rail would likely be on the forend (the thing you "pump" after each shot, the thing that goes chuck-chuck). This isn't an adequate position for a shell holder, since a filled holder would interfere with one's ability to grip the forend. See this replacement forend with an underbarrel rail and two side rails:

https://trinitysupply.com/cdn/shop/files/2_042cc13a-522b-42f6-9c74-c1022d30baed.jpg

But since we don't have a "body" location or something, rails would do.

Copy link
Contributor Author

@worm-girl worm-girl Jan 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

I don't see any that fit on the forend, but I see a bunch that straddle the receiver and add a top rail to the gun. Not sure how we'd represent that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
I guess there are these, but this doesn't look like something that would fit on any old gun. I think my PR will just add generally-applicable mods and I'll leave the hyper-specifics to others.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They don't necessarily go over the top. Looks like they're mostly held by the pins(?) on the shotgun's body, as can be seen in the (poor-quality, but legible) instructions on this product:

https://www.amazon.com/TacStar-6-Shot-Sidesaddle-Black/dp/B001AMZXQI

Which, again, might require a special slot on shotguns, which may or may not be beyond this PR's scope.

"mod_targets": [ "shotgun" ],
"pocket_mods": [
{
"pocket_type": "CONTAINER",
"rigid": true,
"max_contains_volume": "120 ml",
"max_contains_weight": "300 g",
"ammo_restriction": { "shot": 6 },
"moves": 25
}
],
"min_skills": [ [ "weapon", 1 ] ]
}
]
1 change: 1 addition & 0 deletions src/character_ammo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ item::reload_option Character::select_ammo( const item_location &base,
item::reload_option Character::select_ammo( const item_location &base, bool prompt,
bool empty ) const
{

if( !base ) {
return item::reload_option();
}
Expand Down
5 changes: 3 additions & 2 deletions src/character_guns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ void find_ammo_helper( T &src, const item &obj, bool empty, Output out, bool nes
src.visit_items( [&src, &nested, &out, &obj, empty]( item * node, item * parent ) {

// This stops containers and magazines counting *themselves* as ammo sources
if( node == &obj ) {
if( node == &obj && !node->has_flag( flag_NOT_MAGAZINE ) ) {
return VisitResponse::SKIP;
}

Expand All @@ -32,7 +32,7 @@ void find_ammo_helper( T &src, const item &obj, bool empty, Output out, bool nes
}

// Do not steal ammo from magazines
if( parent != nullptr && parent->is_magazine() ) {
if( parent != nullptr && parent->is_magazine() && !parent->is_magazine() ) {
return VisitResponse::SKIP;
}

Expand Down Expand Up @@ -252,6 +252,7 @@ bool Character::gunmod_remove( item &gun, item &mod )
break;
}
}

if( gunmod_idx == mods.size() ) {
debugmsg( "Cannot remove non-existent gunmod" );
return false;
Expand Down
1 change: 1 addition & 0 deletions src/flag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ const flag_id flag_NO_TURRET( "NO_TURRET" );
const flag_id flag_NO_UNLOAD( "NO_UNLOAD" );
const flag_id flag_NO_UNWIELD( "NO_UNWIELD" );
const flag_id flag_NO_WEAR_EFFECT( "NO_WEAR_EFFECT" );
const flag_id flag_NOT_MAGAZINE( "NOT_MAGAZINE" );
const flag_id flag_NPC_ACTIVATE( "NPC_ACTIVATE" );
const flag_id flag_NPC_ALT_ATTACK( "NPC_ALT_ATTACK" );
const flag_id flag_NPC_SAFE( "NPC_SAFE" );
Expand Down
1 change: 1 addition & 0 deletions src/flag.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ extern const flag_id flag_NO_TURRET;
extern const flag_id flag_NO_UNLOAD;
extern const flag_id flag_NO_UNWIELD;
extern const flag_id flag_NO_WEAR_EFFECT;
extern const flag_id flag_NOT_MAGAZINE;
extern const flag_id flag_NPC_ACTIVATE;
extern const flag_id flag_NPC_ALT_ATTACK;
extern const flag_id flag_NPC_SAFE;
Expand Down
5 changes: 3 additions & 2 deletions src/item_pocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1715,7 +1715,6 @@ bool item_pocket::can_reload_with( const item &ammo, const bool now ) const
}

return true;

} else if( is_type( pocket_type::MAGAZINE_WELL ) ) {
// Reloading is refused if there already is full magazine here
// Reloading with another identical mag with identical contents is also pointless so it is not allowed
Expand All @@ -1725,10 +1724,12 @@ bool item_pocket::can_reload_with( const item &ammo, const bool now ) const
front().same_contents( ammo ) );
} else if( is_type( pocket_type::CONTAINER ) ) {
// Reloading is possible if liquid combines with old liquid

if( front().can_combine( ammo ) ) {
return true;
}
if( !ammo.made_of( phase_id::LIQUID ) ) {
return true;
}
}
}
return false;
Expand Down