diff --git a/src/combat.cpp b/src/combat.cpp index ffd25ec0e21..08a76644b11 100644 --- a/src/combat.cpp +++ b/src/combat.cpp @@ -405,12 +405,13 @@ int objArmour(const BASE_OBJECT *psObj, WEAPON_CLASS weaponClass) /* Deals damage to an object * \param psObj object to deal damage to + * \param psProjectile projectile which hit the object (may be nullptr) * \param damage amount of damage to deal * \param weaponClass the class of the weapon that deals the damage * \param weaponSubClass the subclass of the weapon that deals the damage * \return < 0 when the dealt damage destroys the object, > 0 when the object survives */ -int32_t objDamage(BASE_OBJECT *psObj, unsigned damage, unsigned originalhp, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, bool isDamagePerSecond, int minDamage, bool empRadiusHit) +int32_t objDamage(BASE_OBJECT *psObj, PROJECTILE *psProjectile, unsigned damage, unsigned originalhp, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, bool isDamagePerSecond, int minDamage, bool empRadiusHit) { int level = 0; int armour = objArmour(psObj, weaponClass); @@ -527,22 +528,22 @@ int32_t objDamage(BASE_OBJECT *psObj, unsigned damage, unsigned originalhp, WEAP psDroid->shieldInterruptRegenTime = psDroid->time; } - if (weaponSubClass != WSC_FLAME && + if (psProjectile != nullptr && + weaponSubClass != WSC_FLAME && weaponSubClass != WSC_COMMAND && PERCENT(psDroid->shieldPoints, droidGetMaxShieldPoints(psDroid)) > 25) { Vector3i dv; - dv.y = psDroid->pos.z; - dv.y += (psDroid->sDisplay.imd->max.y * 2); + dv.y = psProjectile->pos.z; for (uint32_t i = 0; i < DROID_SHIELD_PARTICLES; i++) { - dv.x = psDroid->pos.x + DROID_SHIELD_DAMAGE_SPREAD; - dv.z = psDroid->pos.y + DROID_SHIELD_DAMAGE_SPREAD; + dv.x = psProjectile->pos.x + DROID_SHIELD_DAMAGE_SPREAD; + dv.z = psProjectile->pos.y + DROID_SHIELD_DAMAGE_SPREAD; addEffect(&dv, EFFECT_FIREWORK, FIREWORK_TYPE_STARBURST, false, nullptr, 0, gameTime - deltaGameTime + 1); } - audio_PlayStaticTrack(psDroid->pos.x, psDroid->pos.y, ID_SOUND_SHIELD_HIT); + audio_PlayStaticTrack(psProjectile->pos.x, psProjectile->pos.y, ID_SOUND_SHIELD_HIT); } } } diff --git a/src/combat.h b/src/combat.h index da45e87bd8e..f5548bbe228 100644 --- a/src/combat.h +++ b/src/combat.h @@ -25,6 +25,7 @@ #define __INCLUDED_SRC_COMBAT_H__ #include "weapondef.h" +#include "objectdef.h" /* Fire a weapon at something added int weapon_slot*/ bool combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, int weapon_slot); @@ -33,7 +34,7 @@ bool combFire(WEAPON *psWeap, BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget, in if any support a counter battery sensor*/ void counterBatteryFire(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget); -int32_t objDamage(BASE_OBJECT *psObj, unsigned damage, unsigned originalhp, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, bool isDamagePerSecond, int minDamage, bool empRadiusHit); +int32_t objDamage(BASE_OBJECT *psObj, PROJECTILE *psProjectile, unsigned damage, unsigned originalhp, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, bool isDamagePerSecond, int minDamage, bool empRadiusHit); unsigned int objGuessFutureDamage(WEAPON_STATS *psStats, unsigned int player, BASE_OBJECT *psTarget); diff --git a/src/droid.cpp b/src/droid.cpp index 43e0308fa1e..8141caf85b4 100644 --- a/src/droid.cpp +++ b/src/droid.cpp @@ -280,6 +280,7 @@ void addDroidDeathAnimationEffect(DROID *psDroid) #define UNIT_LOST_DELAY (5*GAME_TICKS_PER_SEC) /* Deals damage to a droid * \param psDroid droid to deal damage to + * \param psProjectile projectile which hit the object (may be nullptr) * \param damage amount of damage to deal * \param weaponClass the class of the weapon that deals the damage * \param weaponSubClass the subclass of the weapon that deals the damage @@ -287,7 +288,7 @@ void addDroidDeathAnimationEffect(DROID *psDroid) * \return > 0 when the dealt damage destroys the droid, < 0 when the droid survives * */ -int32_t droidDamage(DROID *psDroid, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime, bool isDamagePerSecond, int minDamage, bool empRadiusHit) +int32_t droidDamage(DROID *psDroid, PROJECTILE *psProjectile, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime, bool isDamagePerSecond, int minDamage, bool empRadiusHit) { int32_t relativeDamage; @@ -299,7 +300,7 @@ int32_t droidDamage(DROID *psDroid, unsigned damage, WEAPON_CLASS weaponClass, W damage *= 3; } - relativeDamage = objDamage(psDroid, damage, psDroid->originalBody, weaponClass, weaponSubClass, isDamagePerSecond, minDamage, empRadiusHit); + relativeDamage = objDamage(psDroid, psProjectile, damage, psDroid->originalBody, weaponClass, weaponSubClass, isDamagePerSecond, minDamage, empRadiusHit); if (relativeDamage != 0 && psDroid->player == selectedPlayer && psDroid->timeLastHit == gameTime) { @@ -929,7 +930,7 @@ void droidUpdate(DROID *psDroid) else { // do hardcoded burn damage (this damage automatically applied after periodical damage finished) - droidDamage(psDroid, BURN_DAMAGE, WC_HEAT, WSC_FLAME, gameTime - deltaGameTime / 2 + 1, true, BURN_MIN_DAMAGE, false); + droidDamage(psDroid, nullptr, BURN_DAMAGE, WC_HEAT, WSC_FLAME, gameTime - deltaGameTime / 2 + 1, true, BURN_MIN_DAMAGE, false); } } diff --git a/src/droid.h b/src/droid.h index 44365826c2b..f7bc8c773f6 100644 --- a/src/droid.h +++ b/src/droid.h @@ -113,7 +113,7 @@ UDWORD calcTemplateBuild(const DROID_TEMPLATE *psTemplate); UDWORD calcTemplatePower(const DROID_TEMPLATE *psTemplate); /* Do damage to a droid */ -int32_t droidDamage(DROID *psDroid, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime, bool isDamagePerSecond, int minDamage, bool empRadiusHit); +int32_t droidDamage(DROID *psDroid, PROJECTILE *psProjectile, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime, bool isDamagePerSecond, int minDamage, bool empRadiusHit); /* The main update routine for all droids */ void droidUpdate(DROID *psDroid); diff --git a/src/feature.cpp b/src/feature.cpp index dde621597dd..a76e36649a9 100644 --- a/src/feature.cpp +++ b/src/feature.cpp @@ -160,7 +160,7 @@ int32_t featureDamage(FEATURE *psFeature, unsigned damage, WEAPON_CLASS weaponCl debug(LOG_ATTACK, "feature (id %d): body %d armour %d damage: %d", psFeature->id, psFeature->body, psFeature->psStats->armourValue, damage); - relativeDamage = objDamage(psFeature, damage, psFeature->psStats->body, weaponClass, weaponSubClass, isDamagePerSecond, minDamage, empRadiusHit); + relativeDamage = objDamage(psFeature, nullptr, damage, psFeature->psStats->body, weaponClass, weaponSubClass, isDamagePerSecond, minDamage, empRadiusHit); // If the shell did sufficient damage to destroy the feature if (relativeDamage < 0) diff --git a/src/projectile.cpp b/src/projectile.cpp index 46d2800c9ab..b66aa8091b8 100644 --- a/src/projectile.cpp +++ b/src/projectile.cpp @@ -1687,7 +1687,7 @@ static int32_t objectDamageDispatch(DAMAGE *psDamage) switch (psDamage->psDest->type) { case OBJ_DROID: - return droidDamage((DROID *)psDamage->psDest, psDamage->damage, psDamage->weaponClass, psDamage->weaponSubClass, psDamage->impactTime, psDamage->isDamagePerSecond, psDamage->minDamage, psDamage->empRadiusHit); + return droidDamage((DROID *)psDamage->psDest, psDamage->psProjectile, psDamage->damage, psDamage->weaponClass, psDamage->weaponSubClass, psDamage->impactTime, psDamage->isDamagePerSecond, psDamage->minDamage, psDamage->empRadiusHit); break; case OBJ_STRUCTURE: diff --git a/src/structure.cpp b/src/structure.cpp index 6e5b4477a58..a3674dee2d7 100644 --- a/src/structure.cpp +++ b/src/structure.cpp @@ -832,7 +832,7 @@ int32_t structureDamage(STRUCTURE *psStructure, unsigned damage, WEAPON_CLASS we debug(LOG_ATTACK, "structure id %d, body %d, armour %d, damage: %d", psStructure->id, psStructure->body, objArmour(psStructure, weaponClass), damage); - relativeDamage = objDamage(psStructure, damage, psStructure->structureBody(), weaponClass, weaponSubClass, isDamagePerSecond, minDamage, empRadiusHit); + relativeDamage = objDamage(psStructure, nullptr, damage, psStructure->structureBody(), weaponClass, weaponSubClass, isDamagePerSecond, minDamage, empRadiusHit); // If the shell did sufficient damage to destroy the structure if (relativeDamage < 0)