Here are the changes that I made to the source code: (now out of date, will modify later)
In src/Battlescape/ProjectileFlyBState.cpp, changed these lines under ProjectileFlyBState::think() from
https:// special shotgun behaviour: trace extra projectile paths, and add bullet hits at their termination points.
if (shotgun)
{
int i = 1;
while (i != _ammo->getRules()->getShotgunPellets())
{
https:// create a projectile
Projectile *proj = new Projectile(_parent->getMod(), _parent->getSave(), _action, _origin, _targetVoxel, _ammo);
https:// let it trace to the point where it hits
_projectileImpact = proj->calculateTrajectory(std::max(0.0, (_unit->getFiringAccuracy(_action.type, _action.weapon, _parent->getMod()) / 100.0) - i * 5.0));
to
https:// special shotgun behaviour: trace extra projectile paths, and add bullet hits at their termination points.
if (shotgun)
{
int spread = _ammo->getRules()->getShotgunSpread();
int choke = _action.weapon->getRules()->getShotgunChoke();
Position firstPelletImpact = _targetVoxel;
int i = 1;
while (i != _ammo->getRules()->getShotgunPellets())
{
https:// create a projectile
Projectile *proj = new Projectile(_parent->getMod(), _parent->getSave(), _action, _origin, _targetVoxel, _ammo);
https:// which type of shotgun behavior to use?
bool groupingBehavior = _ammo->getRules()->getShotgunBehavior();
if (!groupingBehavior)
{
https:// let it trace to the point where it hits
_projectileImpact = proj->calculateTrajectory(std::max(0.0, (_unit->getFiringAccuracy(_action.type, _action.weapon, _parent->getMod()) / 100.0) - i * 5.0 * spread / 100.0));
}
https:// pellet spread based on where first pellet hit
else
{
_targetVoxel = firstPelletImpact;
_projectileImpact = proj->calculateTrajectory(std::max(0.0, (1.0 - spread / 100.0) * choke / 100.0));
}
To expose the calculates to the ruleset, in src/Mod/RuleItem.cpp, the line
_maxRange(200), _aimRange(200), _snapRange(15), _autoRange(7), _minRange(0), _dropoff(2), _bulletSpeed(0), _explosionSpeed(0), _autoShots(3), _shotgunPellets(0),
was changed to
_maxRange(200), _aimRange(200), _snapRange(15), _autoRange(7), _minRange(0), _dropoff(2), _bulletSpeed(0), _explosionSpeed(0), _autoShots(3), _shotgunPellets(0), _shotgunSpread(100), _shotgunBehavior(false), _shotgunChoke(100),
and the following lines were added to RuleItem::load()
_shotgunSpread = node["shotgunSpread"].as<int>(_shotgunSpread);
_shotgunBehavior = node["shotgunBehavior"].as<bool>(_shotgunBehavior);
_shotgunChoke = node["shotgunChoke"].as<int>(_shotgunChoke);
with the functions
/**
* Gets the spread of projectiles from this ammo for use in shotgun behavior.
* @return The spread.
*/
int RuleItem::getShotgunSpread() const
{
return _shotgunSpread;
}
/**
* Do the shotgun pellets follow a grouping, or just fired in a cone-like behavior?
* @return false => cone-like spread, true => grouping
*/
bool RuleItem::getShotgunBehavior() const
{
return _shotgunBehavior;
}
/**
* Gets the shotgun choke value for modifying pellet spread
* @return weapon shotgun choke value
*/
int RuleItem::getShotgunChoke() const
{
return _shotgunChoke;
}
Finally, the variables were added to RuleItem.h
int _listOrder, _maxRange, _aimRange, _snapRange, _autoRange, _minRange, _dropoff, _bulletSpeed, _explosionSpeed, _autoShots, _shotgunPellets, _shotgunSpread;
bool _shotgunBehavior;
int _shotgunChoke;
and
https:/// Get the spread of projectiles with shotgun behavior.
int getShotgunSpread() const;
https:/// Get which shotgun spread behavior to use.
bool getShotgunBehavior() const;
https:/// Get the shotgun choke value of this weapon.
int getShotgunChoke() const;