Skip to content
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
4 changes: 3 additions & 1 deletion GeneralsMD/Code/GameEngine/Include/GameLogic/Weapon.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ class WeaponTemplate : public MemoryPoolObject
inline Real getLaserGroundUnitTargetHeight() const { return m_laserGroundUnitTargetHeight; }
inline Real getLaserGroundTargetHeight() const { return m_laserGroundTargetHeight; }
inline UnsignedInt getScatterTargetResetTime() const { return m_scatterTargetResetTime; }
inline Bool isScatterTargetResetRecenter() const { return m_scatterTargetResetRecenter; }
inline const std::vector<Coord2D>& getScatterTargetsVector() const { return m_scatterTargets; }
inline const WeaponBonusSet* getExtraBonus() const { return m_extraBonus; }
inline Int getShotsPerBarrel() const { return m_shotsPerBarrel; }
Expand Down Expand Up @@ -600,6 +601,7 @@ class WeaponTemplate : public MemoryPoolObject
Bool m_scatterTargetCenteredAtShooter; ///< if the scatter target pattern is centered at the shooter

UnsignedInt m_scatterTargetResetTime; ///< if this much time between shots has passed, we reset the scatter targets
Bool m_scatterTargetResetRecenter; ///< when resetting scatter targets, use indices in the "middle" of the list, to keep the target centered for Line based attacks

mutable HistoricWeaponDamageList m_historicDamage;
};
Expand Down Expand Up @@ -838,7 +840,7 @@ class Weapon : public MemoryPoolObject,

void computeBonus(const Object *source, WeaponBonusConditionFlags extraBonusFlags, WeaponBonus& bonus) const;

void rebuildScatterTargets();
void rebuildScatterTargets(Bool recenter = false);


private:
Expand Down
25 changes: 20 additions & 5 deletions GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ const FieldParse WeaponTemplate::TheWeaponTemplateFieldParseTable[] =
{ "ScatterTargetMinScalar", INI::parseReal, NULL, offsetof(WeaponTemplate, m_scatterTargetMinScalar) },
{ "ScatterTargetCenteredAtShooter", INI::parseBool, NULL, offsetof(WeaponTemplate, m_scatterTargetCenteredAtShooter) },
{ "ScatterTargetResetTime", INI::parseDurationUnsignedInt, NULL, offsetof(WeaponTemplate, m_scatterTargetResetTime) },
{ "ScatterTargetResetRecenter", INI::parseBool, NULL, offsetof(WeaponTemplate, m_scatterTargetResetRecenter) },
{ "PreAttackFX", parseAllVetLevelsFXList, NULL, offsetof(WeaponTemplate, m_preAttackFXs) },
{ "VeterancyPreAttackFX", parsePerVetLevelFXList, NULL, offsetof(WeaponTemplate, m_preAttackFXs) },
{ "PreAttackFXDelay", INI::parseDurationUnsignedInt, NULL, offsetof(WeaponTemplate, m_preAttackFXDelay) },
Expand Down Expand Up @@ -2017,15 +2018,29 @@ void Weapon::setClipPercentFull(Real percent, Bool allowReduction)
}

//-------------------------------------------------------------------------------------------------
void Weapon::rebuildScatterTargets()
void Weapon::rebuildScatterTargets(Bool recenter/* = false*/)
{
m_scatterTargetsUnused.clear();
Int scatterTargetsCount = m_template->getScatterTargetsVector().size();
if (scatterTargetsCount)
{
// When I reload, I need to rebuild the list of ScatterTargets to shoot at.
for (Int targetIndex = scatterTargetsCount - 1; targetIndex >= 0; targetIndex--)
m_scatterTargetsUnused.push_back(targetIndex);
if (recenter && m_ammoInClip > 0 && m_ammoInClip < m_template->getClipSize() && m_template->getClipSize() > 0) {
// Recenter case is relevant when we have "sweep" target set up in a line around the target.
// When we reset, we want to keep the next shots around the target, which would be the
// indices in the center of the list.
UnsignedInt startIndex = REAL_TO_INT_FLOOR((m_template->getClipSize() - m_ammoInClip) / 2);
for (Int targetIndex = startIndex + m_ammoInClip - 1; targetIndex >= startIndex; targetIndex--) {
m_scatterTargetsUnused.push_back(targetIndex);
}
// TODO: Crash
// Is there any need to fill up the rest of the targets?
}
else {
// When I reload, I need to rebuild the list of ScatterTargets to shoot at.
for (Int targetIndex = scatterTargetsCount - 1; targetIndex >= 0; targetIndex--)
m_scatterTargetsUnused.push_back(targetIndex);
}


if (m_template->isScatterTargetRandomAngle()) {
m_scatterTargetsAngle = GameLogicRandomValueReal(0, PI * 2);
Expand Down Expand Up @@ -2805,7 +2820,7 @@ Bool Weapon::privateFireWeapon(
if (m_template->getScatterTargetResetTime() > 0) {
UnsignedInt frameNow = TheGameLogic->getFrame();
if (m_lastFireFrame + m_template->getScatterTargetResetTime() < frameNow) {
rebuildScatterTargets();
rebuildScatterTargets(m_template->isScatterTargetResetRecenter());
}
}

Expand Down