# Heavy vehiclular weapons implementation (with C++ code)

**URL:** <https://discourse.cataclysmdda.org/t/heavy-vehiclular-weapons-implementation-with-c-code/28986>\
**Category:** The Lab\
**Created:** [August 28, 2023, 1:58pm UTC](https://discourse.cataclysmdda.org/t/heavy-vehiclular-weapons-implementation-with-c-code/28986 "2023-08-28T13:58:08Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![AtomicFox556](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.cataclysmdda.org/atomicfox556/32/12453_2.png) [@AtomicFox556](https://discourse.cataclysmdda.org/u/AtomicFox556)\
**Post date:** [August 28, 2023, 1:58pm UTC](https://discourse.cataclysmdda.org/t/heavy-vehiclular-weapons-implementation-with-c-code/28986/1 "2023-08-28T13:58:08Z")

</div>

I’ve made and decided to share on here a simple-ish C++ implementation of proper support for heavy vehicular weapons that prevent firing said weapons from bicycles, shopping carts or similar light vehicles, as was the issue with how Tankmod had tank guns implemented.

The way it is currently done is as such:

Any vehicle-only guns get the JSON flag called “VEHICLE\_GUN\_ONLY”.

If a gun with this flag is mounted on a vehicle which has total mass lower than the mass defined in “min\_veh\_mass” JSON field of a gun item, then said gun can’t be fired.

Furthermore, if a gun with this flag is installed on a vehicle tile with has no parts with a new “MOUNTABLE\_HEAVY” JSON flag (which usually is a heavy-duty frame), then the gun can’t be fired either.

The code additions are below. Anyone feel free to make a pull request with it, but note that code may or may not need minor updates for the most recent experimental version of DDA. Suggestions are welcome.

- File `avatar_action.cpp`:  
Function `avatar_action::fire_turret_manual`: this code defines the logic behind forbidding firing vehicular weapons from an unsuitable vehicle.

```auto
if( turret.base()->has_flag( flag_VEHICLE_GUN_ONLY ) ) {
        const optional_vpart_position vp = m.veh_at( you.pos() );
        vehicle *veh = veh_pointer_or_null( vp );
        if( !veh ) {
            debugmsg( "Vehicle not found on fired vehicular weapon tile." );
            return false;
        }
        if( !static_cast<bool>( vp.part_with_feature( "MOUNTABLE_HEAVY", true ) ) ) {
            add_msg( m_bad, _( "This vehicle's frame is not durable enough to handle the recoil of the %s." ),
                     turret.name() );
            return false;
        }
        if( veh->total_mass() < turret.base()->get_min_veh_mass() ) {
            add_msg( m_bad, _( "This vehicle is too light to safely fire the %s." ), turret.name() );
            return false;
        }
    }

```

Function `avatar_action::fire_wielded_weapon`: show failure text if player tries to fire a vehicle-only weapon while wielding it.

```auto
if( weapon->has_flag( flag_VEHICLE_GUN_ONLY ) ) {
        add_msg( m_info,
                 _( "Your %s must be mounted on a vehicle with a sturdy frame and enough mass to fire." ),
                 weapon->tname() );
        return;
    }

```

- File `flag.cpp`: define new flag.

```auto
const flag_id flag_VEHICLE_GUN_ONLY( "VEHICLE_GUN_ONLY" );

```

- File `flag.h`: define new flag.

```auto
extern const flag_id flag_VEHICLE_GUN_ONLY;

```

- File `item.cpp`:  
Function `item::gun_info`: code to display minimum vehicle mass in gun info; insert after the code to display barrel length.

```auto
    if( mod->get_min_veh_mass().value() > 0 ) {
        if( parts->test( iteminfo_parts::GUN_MIN_VEH_MASS ) ) {
            info.emplace_back( weight_to_info( "GUN", _( "Minimum Vehicle Mass: " ), get_min_veh_mass() ) );
        }
    }
    info.back().bNewLine = true;

```

New function to get minimum vehicle mass from item data:

```auto
units::mass item::get_min_veh_mass() const
{
    return type->min_veh_mass;
}

```

- File `item.h`: defining the new function above.

```auto
        units::mass get_min_veh_mass() const;

```

- File `item_factory.cpp`, function `Item_factory::load_basic_info`: load minimum vehicle mass field from JSON.

```auto
    assign( jo, "min_veh_mass", def.min_veh_mass, false, 0_gram );

```

- File `iteminfo_query.h`, `enum class iteminfo_parts` : add `GUN_MIN_VEH_MASS` after `GUN_BARRELLENGTH` to get minimum vehicle mass data to display in item description.

- File `turret.cpp`: replace `vehicle::find_all_ready_turrets` function with this one:

```auto
std::vector<vehicle_part *> vehicle::find_all_ready_turrets( bool manual, bool automatic )
{
    std::vector<vehicle_part *> res;
    for( vehicle_part *t : turrets() ) {
        if( ( t->enabled && automatic ) || ( !t->enabled && manual ) ) {
            if( turret_query( *t ).query() == turret_data::status::ready ) {
                turret_data turret_here = turret_query( global_part_pos3( *t ) );
                if( turret_here.base()->has_flag( flag_VEHICLE_GUN_ONLY ) ) {
                    if( !has_part( global_part_pos3( *t ), "MOUNTABLE_HEAVY", false ) ||
                        total_mass() < turret_here.base()->get_min_veh_mass() ) {
                        continue;
                    }
                }
                res.push_back( t );
            }
        }
    }
    return res;
}

```

Also add `#include "flag.h"` to the file.

Sample gun JSON data to test this mechanic with:

```auto
{
    "id": "gau19",
    "copy-from": "rifle_auto",
    "looks_like": "m2browning",
    "type": "GUN",
    "name": { "str_sp": "GAU-19/B" },
    "description": "An electrically driven, three-barrel rotary heavy machine gun firing a .50 BMG cartridge. If you could find enough ammo for it, it would become a devastating weapon. It must be mounted on a heavy vehicle frame before use.",
    "weight": "48 kg",
    "volume": "12 L",
    "longest_side": "1369 mm",
    "barrel_length": "914 mm",
    "price": 1800000,
    "price_postapoc": 10000,
    "to_hit": -4,
    "material": ["qt_steel"],
    "ammo": ["50"],
    "range": 110,
    "dispersion": 250,
    "durability": 9,
    "blackpowder_tolerance": 96,
    "energy_drain": "1 kJ",
    "reload": 400,
    "modes": [[ "DEFAULT", "low auto", 6], ["AUTO", "high auto", 50] ],
    "valid_mod_locations": [[ "sling", 1] ],
    "min_veh_mass": "250 kg",
    "flags": ["NEVER_JAMS", "VEHICLE_GUN_ONLY", "USE_UPS"],
    "pocket_data": [{ "pocket_type": "MAGAZINE_WELL", "item_restriction": [ "belt50"] } ],
    "melee_damage": { "bash": 18 }
  }

```

---

<div class="post-metadata">

**Author:** ![Pupker](https://avatars.discourse-cdn.com/v4/letter/p/ad7895/32.png) [@Pupker](https://discourse.cataclysmdda.org/u/Pupker)\
**Post date:** [August 29, 2023, 3:20am UTC](https://discourse.cataclysmdda.org/t/heavy-vehiclular-weapons-implementation-with-c-code/28986/2 "2023-08-29T03:20:43Z")

</div>

Could you make it so it only prevents firing while driving? If you dismount the vehicle and grab it then it should be possible to fire basically anything. Most towed artillery guns are like that, their chassis is just 1 frame +1 foldable frame in CDDA terms, with the gun often outweighting the chassis. Also consider these:

 ![cartgun](https://us1.discourse-cdn.com/flex016/uploads/cataclysmdda/original/2X/a/a2f84da4bddda94e1622376e2b0be43bbda4f4b0.jpeg)  
 ![wheelbarrowgun](https://us1.discourse-cdn.com/flex016/uploads/cataclysmdda/original/2X/2/20a6a7ebf30d9d84cddd0c1e01968195ddf02506.jpeg)

---

<div class="post-metadata">

**Author:** ![AtomicFox556](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.cataclysmdda.org/atomicfox556/32/12453_2.png) [@AtomicFox556](https://discourse.cataclysmdda.org/u/AtomicFox556)\
**Post date:** [August 29, 2023, 4:04am UTC](https://discourse.cataclysmdda.org/t/heavy-vehiclular-weapons-implementation-with-c-code/28986/3 "2023-08-29T04:04:49Z")

</div>

This implementation is meant for weapons heavier than those, lighter weapons up to and including M2HB can already be mounted on anything. Trying to do that with an autocannon or a tank cannon would knock over the user.

---

<div class="post-metadata">

**Author:** ![Pupker](https://avatars.discourse-cdn.com/v4/letter/p/ad7895/32.png) [@Pupker](https://discourse.cataclysmdda.org/u/Pupker)\
**Post date:** [August 29, 2023, 1:51pm UTC](https://discourse.cataclysmdda.org/t/heavy-vehiclular-weapons-implementation-with-c-code/28986/4 "2023-08-29T13:51:03Z")

</div>

Now that I think about it, you could actually provide the mechanic that would do everything you want without having to manually set those values. Considering that gun ammo and rate of fire are known, you can calculate momentum each shot/burst provides and apply it to the vehicle. You could still mount tank gun on a single frame but firing it would accelerate it to 50mph and smear you over asphalt. Perhaps PC could absorb some momentum depending on the strength value to allow mutants more leeway.  
It just doesn’t make sense to not allow doing stupid things which are possible in reality just because they’re stupid.

---

<div class="post-metadata">

**Author:** ![AtomicFox556](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.cataclysmdda.org/atomicfox556/32/12453_2.png) [@AtomicFox556](https://discourse.cataclysmdda.org/u/AtomicFox556)\
**Post date:** [August 29, 2023, 5:17pm UTC](https://discourse.cataclysmdda.org/t/heavy-vehiclular-weapons-implementation-with-c-code/28986/5 "2023-08-29T17:17:37Z")

</div>

Well, first of all, at a glance implementing fired turrets affecting the vehicle’s movement seems extremely complicated to code. Given that it’s not even an expected use case of such weapons, I don’t feel like coding something like that if it would be used extremely rarely.

Second, this needs a clear way to communicate to the player that firing a tank gun mounted on a shopping cart is obviously a bad idea. I don’t know how this could be communcated clear enough, personally.

Third, cyclic rate of fire for guns isn’t really defined anywhere in a way that is actually consistent; last time I calculated it, current burst sizes for at least some full-auto guns, combined with amount of moves spent on firing the gun without aiming, allow you to mag-dump faster than the gun can actually fire. This can be fixed but it would be tedious to edit everything.

For as long as those are an issue, I think it’d be much easier to just have such a weight limit (which would assume that the vehicle wouldn’t move around noticeably due to recoil) and durable frame requirement (which would assume that the vehicle itself isn’t damaged by recoil) in place.

---

<div class="post-metadata">

**Author:** ![Pupker](https://avatars.discourse-cdn.com/v4/letter/p/ad7895/32.png) [@Pupker](https://discourse.cataclysmdda.org/u/Pupker)\
**Post date:** [August 30, 2023, 3:57am UTC](https://discourse.cataclysmdda.org/t/heavy-vehiclular-weapons-implementation-with-c-code/28986/6 "2023-08-30T03:57:00Z")

</div>

However, such a mechanic would also be useful in other places. For example, aircraft. And you dont need to know the rate of fire beforehand, you can just apply momentum of a round after every single shot.
