Simplify incendary damage, fix incendary armour.
Apply incendary armour before converting from damage-per-second to damage-per-update, such that incendary armour is now a per-second value, rather than a per-update value. Dropped BASE_OBJECT::inFire, the value of which could be determined from BASE_OBJECT::burnStart. Fixes ticket:3078.master
parent
4657de6ee7
commit
666ea1050e
|
@ -96,7 +96,6 @@ struct BASE_OBJECT : public SIMPLE_OBJECT
|
|||
UBYTE cluster; ///< Which cluster the object is a member of
|
||||
UBYTE visible[MAX_PLAYERS]; ///< Whether object is visible to specific player
|
||||
UBYTE seenThisTick[MAX_PLAYERS]; ///< Whether object has been seen this tick by the specific player.
|
||||
UBYTE inFire; ///< true if the object is in a fire
|
||||
UWORD numWatchedTiles; ///< Number of watched tiles, zero for features
|
||||
UDWORD lastEmission; ///< When did it last puff out smoke?
|
||||
WEAPON_SUBCLASS lastHitWeapon; ///< The weapon that last hit it
|
||||
|
|
|
@ -420,7 +420,7 @@ void counterBatteryFire(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget)
|
|||
* \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, UDWORD damage, UDWORD originalhp, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass)
|
||||
int32_t objDamage(BASE_OBJECT *psObj, unsigned damage, unsigned originalhp, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, bool isDamagePerSecond)
|
||||
{
|
||||
int actualDamage, armour, level = 1;
|
||||
|
||||
|
@ -476,8 +476,19 @@ int32_t objDamage(BASE_OBJECT *psObj, UDWORD damage, UDWORD originalhp, WEAPON_C
|
|||
// And at least MIN_WEAPON_DAMAGE points
|
||||
actualDamage = MAX(actualDamage, MIN_WEAPON_DAMAGE);
|
||||
|
||||
if (isDamagePerSecond)
|
||||
{
|
||||
int deltaDamageRate = actualDamage - psObj->burnDamage;
|
||||
if (deltaDamageRate <= 0)
|
||||
{
|
||||
return 0; // Did this much damage already, this tick, so don't do more.
|
||||
}
|
||||
actualDamage = gameTimeAdjustedAverage(deltaDamageRate);
|
||||
psObj->burnDamage += deltaDamageRate;
|
||||
}
|
||||
|
||||
objTrace(psObj->id, "objDamage: Penetrated %d", actualDamage);
|
||||
syncDebug("damage%u dam%u,o%u,wc%d.%d,ar%d,lev%d,aDam%d", psObj->id, damage, originalhp, weaponClass, weaponSubClass, armour, level, actualDamage);
|
||||
syncDebug("damage%u dam%u,o%u,wc%d.%d,ar%d,lev%d,aDam%d,isDps%d", psObj->id, damage, originalhp, weaponClass, weaponSubClass, armour, level, actualDamage, isDamagePerSecond);
|
||||
|
||||
// for some odd reason, we have 0 hitpoints.
|
||||
if (!originalhp)
|
||||
|
|
|
@ -48,7 +48,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, UDWORD damage, UDWORD originalhp, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass);
|
||||
int32_t objDamage(BASE_OBJECT *psObj, unsigned damage, unsigned originalhp, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, bool isDamagePerSecond);
|
||||
|
||||
unsigned int objGuessFutureDamage(WEAPON_STATS *psStats, unsigned int player, BASE_OBJECT *psTarget);
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ bool droidInit(void)
|
|||
*
|
||||
* NOTE: This function will damage but _never_ destroy transports when in single player (campaign) mode
|
||||
*/
|
||||
int32_t droidDamage(DROID *psDroid, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime)
|
||||
int32_t droidDamage(DROID *psDroid, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime, bool isDamagePerSecond)
|
||||
{
|
||||
int32_t relativeDamage;
|
||||
|
||||
|
@ -165,7 +165,7 @@ int32_t droidDamage(DROID *psDroid, unsigned damage, WEAPON_CLASS weaponClass, W
|
|||
damage *= 3;
|
||||
}
|
||||
|
||||
relativeDamage = objDamage((BASE_OBJECT *)psDroid, damage, psDroid->originalBody, weaponClass, weaponSubClass);
|
||||
relativeDamage = objDamage(psDroid, damage, psDroid->originalBody, weaponClass, weaponSubClass, isDamagePerSecond);
|
||||
|
||||
if (relativeDamage > 0)
|
||||
{
|
||||
|
@ -736,7 +736,6 @@ void droidUpdate(DROID *psDroid)
|
|||
Vector3i dv;
|
||||
UDWORD percentDamage, emissionInterval;
|
||||
BASE_OBJECT *psBeingTargetted = NULL;
|
||||
SDWORD damageToDo;
|
||||
unsigned i;
|
||||
|
||||
CHECK_DROID(psDroid);
|
||||
|
@ -836,43 +835,19 @@ void droidUpdate(DROID *psDroid)
|
|||
// -----------------
|
||||
|
||||
/* Update the fire damage data */
|
||||
if (psDroid->inFire & IN_FIRE)
|
||||
if (psDroid->burnStart != 0 && psDroid->burnStart != gameTime - deltaGameTime) // -deltaGameTime, since projectiles are updated after droids.
|
||||
{
|
||||
/* Still in a fire, reset the fire flag to see if we get out this turn */
|
||||
psDroid->inFire = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The fire flag has not been set so we must be out of the fire */
|
||||
if (psDroid->inFire & BURNING)
|
||||
// The burnStart has been set, but is not from the previous tick, so we must be out of the fire.
|
||||
psDroid->burnDamage = 0; // Reset burn damage done this tick.
|
||||
if (psDroid->burnStart + BURN_TIME < gameTime)
|
||||
{
|
||||
if (psDroid->burnStart + BURN_TIME < gameTime)
|
||||
{
|
||||
// stop burning
|
||||
psDroid->inFire = 0;
|
||||
psDroid->burnStart = 0;
|
||||
psDroid->burnDamage = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// do burn damage
|
||||
damageToDo = BURN_DAMAGE * ((SDWORD)gameTime - (SDWORD)psDroid->burnStart) /
|
||||
GAME_TICKS_PER_SEC;
|
||||
damageToDo -= (SDWORD)psDroid->burnDamage;
|
||||
if (damageToDo > 0)
|
||||
{
|
||||
psDroid->burnDamage += damageToDo;
|
||||
|
||||
droidDamage(psDroid, damageToDo, WC_HEAT, WSC_FLAME, gameTime - deltaGameTime/2);
|
||||
}
|
||||
}
|
||||
// Finished burning.
|
||||
psDroid->burnStart = 0;
|
||||
}
|
||||
else if (psDroid->burnStart != 0)
|
||||
else
|
||||
{
|
||||
// just left the fire
|
||||
psDroid->inFire |= BURNING;
|
||||
psDroid->burnStart = gameTime;
|
||||
psDroid->burnDamage = 0;
|
||||
// do burn damage
|
||||
droidDamage(psDroid, BURN_DAMAGE, WC_HEAT, WSC_FLAME, gameTime - deltaGameTime/2, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1968,7 +1943,6 @@ DROID *reallyBuildDroid(DROID_TEMPLATE *pTemplate, Position pos, UDWORD player,
|
|||
}
|
||||
memset(psDroid->seenThisTick, 0, sizeof(psDroid->seenThisTick));
|
||||
psDroid->died = 0;
|
||||
psDroid->inFire = 0;
|
||||
psDroid->burnStart = 0;
|
||||
psDroid->burnDamage = 0;
|
||||
psDroid->sDisplay.screenX = OFF_SCREEN;
|
||||
|
|
|
@ -128,7 +128,7 @@ extern UDWORD calcTemplatePower(DROID_TEMPLATE *psTemplate);
|
|||
bool idfDroid(DROID *psDroid);
|
||||
|
||||
/* Do damage to a droid */
|
||||
int32_t droidDamage(DROID *psDroid, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime);
|
||||
int32_t droidDamage(DROID *psDroid, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime, bool isDamagePerSecond);
|
||||
|
||||
/* The main update routine for all droids */
|
||||
extern void droidUpdate(DROID *psDroid);
|
||||
|
|
|
@ -165,7 +165,7 @@ void featureStatsShutDown(void)
|
|||
* \param weaponClass,weaponSubClass the class and subclass of the weapon that deals the damage
|
||||
* \return < 0 never, >= 0 always
|
||||
*/
|
||||
int32_t featureDamage(FEATURE *psFeature, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime)
|
||||
int32_t featureDamage(FEATURE *psFeature, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime, bool isDamagePerSecond)
|
||||
{
|
||||
int32_t relativeDamage;
|
||||
|
||||
|
@ -174,7 +174,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->armour[weaponClass], damage);
|
||||
|
||||
relativeDamage = objDamage((BASE_OBJECT *)psFeature, damage, psFeature->psStats->body, weaponClass, weaponSubClass);
|
||||
relativeDamage = objDamage(psFeature, damage, psFeature->psStats->body, weaponClass, weaponSubClass, isDamagePerSecond);
|
||||
|
||||
// If the shell did sufficient damage to destroy the feature
|
||||
if (relativeDamage < 0)
|
||||
|
@ -251,7 +251,8 @@ FEATURE * buildFeature(FEATURE_STATS *psStats, UDWORD x, UDWORD y,bool FromSave)
|
|||
psFeature->rot.direction = 0;
|
||||
}
|
||||
psFeature->body = psStats->body;
|
||||
psFeature->inFire = false;
|
||||
psFeature->burnStart = 0;
|
||||
psFeature->burnDamage = 0;
|
||||
objSensorCache(psFeature, NULL);
|
||||
objEcmCache(psFeature, NULL);
|
||||
|
||||
|
@ -355,6 +356,15 @@ void featureUpdate(FEATURE *psFeat)
|
|||
// update the visibility for the feature
|
||||
processVisibilityLevel((BASE_OBJECT *)psFeat);
|
||||
|
||||
/* Update the fire damage data */
|
||||
if (psFeat->burnStart != 0 && psFeat->burnStart != gameTime - deltaGameTime) // -deltaGameTime, since projectiles are updated after features.
|
||||
{
|
||||
// The burnStart has been set, but is not from the previous tick, so we must be out of the fire.
|
||||
psFeat->burnDamage = 0; // Reset burn damage done this tick.
|
||||
// Finished burning.
|
||||
psFeat->burnStart = 0;
|
||||
}
|
||||
|
||||
syncDebugFeature(psFeat, '>');
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ bool destroyFeature(FEATURE *psDel, unsigned impactTime);
|
|||
/* get a feature stat id from its name */
|
||||
extern SDWORD getFeatureStatFromName(const char *pName);
|
||||
|
||||
int32_t featureDamage(FEATURE *psFeature, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime);
|
||||
int32_t featureDamage(FEATURE *psFeature, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime, bool isDamagePerSecond);
|
||||
|
||||
extern void featureInitVars(void);
|
||||
|
||||
|
|
15
src/game.cpp
15
src/game.cpp
|
@ -4213,7 +4213,6 @@ static bool loadSaveDroid(const char *pFileName, DROID **ppsCurrentDroidLists)
|
|||
}
|
||||
ASSERT(id != 0, "Droid ID should never be zero here");
|
||||
psDroid->body = healthValue(ini, psDroid->originalBody);
|
||||
psDroid->inFire = ini.value("inFire", 0).toInt();
|
||||
psDroid->burnDamage = ini.value("burnDamage", 0).toInt();
|
||||
psDroid->burnStart = ini.value("burnStart", 0).toInt();
|
||||
psDroid->experience = ini.value("experience", 0).toInt();
|
||||
|
@ -4397,7 +4396,6 @@ static bool writeDroid(WzConfig &ini, DROID *psCurr, bool onMission, int &counte
|
|||
}
|
||||
if (psCurr->died > 0) ini.setValue("died", psCurr->died);
|
||||
if (psCurr->resistance > 0) ini.setValue("resistance", psCurr->resistance);
|
||||
if (psCurr->inFire > 0) ini.setValue("inFire", psCurr->inFire);
|
||||
if (psCurr->burnStart > 0) ini.setValue("burnStart", psCurr->burnStart);
|
||||
if (psCurr->burnDamage > 0) ini.setValue("burnDamage", psCurr->burnDamage);
|
||||
ini.setValue("droidType", psCurr->droidType);
|
||||
|
@ -4611,7 +4609,6 @@ bool loadSaveStructure(char *pFileData, UDWORD filesize)
|
|||
// The original code here didn't work and so the scriptwriters worked round it by using the module ID - so making it work now will screw up
|
||||
// the scripts -so in ALL CASES overwrite the ID!
|
||||
psStructure->id = psSaveStructure->id > 0 ? psSaveStructure->id : 0xFEDBCA98; // hack to remove struct id zero
|
||||
psStructure->inFire = psSaveStructure->inFire;
|
||||
psStructure->burnDamage = psSaveStructure->burnDamage;
|
||||
burnTime = psSaveStructure->burnStart;
|
||||
psStructure->burnStart = burnTime;
|
||||
|
@ -4737,7 +4734,6 @@ static bool loadSaveStructure2(const char *pFileName, STRUCTURE **ppList)
|
|||
{
|
||||
psStructure->id = id; // force correct ID
|
||||
}
|
||||
psStructure->inFire = ini.value("inFire", 0).toInt();
|
||||
psStructure->burnDamage = ini.value("burnDamage", 0).toInt();
|
||||
psStructure->burnStart = ini.value("burnStart", 0).toInt();
|
||||
memset(psStructure->visible, 0, sizeof(psStructure->visible));
|
||||
|
@ -4953,7 +4949,6 @@ bool writeStructFile(const char *pFileName)
|
|||
}
|
||||
if (psCurr->died > 0) ini.setValue("died", psCurr->died);
|
||||
if (psCurr->resistance > 0) ini.setValue("resistance", psCurr->resistance);
|
||||
if (psCurr->inFire > 0) ini.setValue("inFire", psCurr->inFire);
|
||||
if (psCurr->burnStart > 0) ini.setValue("burnStart", psCurr->burnStart);
|
||||
if (psCurr->burnDamage > 0) ini.setValue("burnDamage", psCurr->burnDamage);
|
||||
if (psCurr->status != SS_BUILT) ini.setValue("status", psCurr->status);
|
||||
|
@ -5260,7 +5255,6 @@ bool loadSaveFeature(char *pFileData, UDWORD filesize)
|
|||
//restore values
|
||||
pFeature->id = psSaveFeature->id;
|
||||
pFeature->rot.direction = DEG(psSaveFeature->direction);
|
||||
pFeature->inFire = psSaveFeature->inFire;
|
||||
pFeature->burnDamage = psSaveFeature->burnDamage;
|
||||
if (psHeader->version >= VERSION_14)
|
||||
{
|
||||
|
@ -5331,7 +5325,6 @@ bool loadSaveFeature2(const char *pFileName)
|
|||
//restore values
|
||||
pFeature->id = ini.value("id").toInt();
|
||||
pFeature->rot = ini.vector3i("rotation");
|
||||
pFeature->inFire = ini.value("inFire", 0).toInt();
|
||||
pFeature->burnDamage = ini.value("burnDamage", 0).toInt();
|
||||
pFeature->burnStart = ini.value("burnStart", 0).toInt();
|
||||
pFeature->born = ini.value("born", 2).toInt();
|
||||
|
@ -5367,12 +5360,8 @@ bool writeFeatureFile(const char *pFileName)
|
|||
ini.setValue("name", psCurr->psStats->pName);
|
||||
ini.setVector3i("position", psCurr->pos);
|
||||
ini.setVector3i("rotation", psCurr->rot);
|
||||
if (psCurr->inFire)
|
||||
{
|
||||
ini.setValue("inFire", psCurr->inFire);
|
||||
ini.setValue("burnDamage", psCurr->burnDamage);
|
||||
ini.setValue("burnStart", psCurr->burnStart);
|
||||
}
|
||||
ini.setValue("burnDamage", psCurr->burnDamage);
|
||||
ini.setValue("burnStart", psCurr->burnStart);
|
||||
ini.setValue("health", psCurr->body);
|
||||
ini.setValue("born", psCurr->born);
|
||||
if (psCurr->selected) ini.setValue("selected", psCurr->selected);
|
||||
|
|
|
@ -2644,7 +2644,7 @@ void moveUpdateDroid(DROID *psDroid)
|
|||
objTrace(psDroid->id, "MOVETURNTOTARGET complete");
|
||||
}
|
||||
|
||||
if( (psDroid->inFire && psDroid->droidType != DROID_PERSON) && psDroid->visible[selectedPlayer])
|
||||
if (psDroid->burnStart != 0 && psDroid->droidType != DROID_PERSON && psDroid->visible[selectedPlayer])
|
||||
{
|
||||
pos.x = psDroid->pos.x + (18-rand()%36);
|
||||
pos.z = psDroid->pos.y + (18-rand()%36);
|
||||
|
|
|
@ -110,7 +110,7 @@ static void proj_ImpactFunc( PROJECTILE *psObj );
|
|||
static void proj_PostImpactFunc( PROJECTILE *psObj );
|
||||
static void proj_checkBurnDamage(PROJECTILE *psProj);
|
||||
|
||||
static int32_t objectDamage(BASE_OBJECT *psObj, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime);
|
||||
static int32_t objectDamage(BASE_OBJECT *psObj, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime, bool isDamagePerSecond);
|
||||
|
||||
|
||||
static inline void setProjectileDestination(PROJECTILE *psProj, BASE_OBJECT *psObj)
|
||||
|
@ -1152,7 +1152,7 @@ static void proj_ImpactFunc( PROJECTILE *psObj )
|
|||
psObj->psDest->id, psObj->psDest->player);
|
||||
|
||||
// Damage the object
|
||||
relativeDamage = objectDamage(psObj->psDest, damage, psStats->weaponClass, psStats->weaponSubClass, psObj->time);
|
||||
relativeDamage = objectDamage(psObj->psDest, damage, psStats->weaponClass, psStats->weaponSubClass, psObj->time, false);
|
||||
|
||||
proj_UpdateKills(psObj, relativeDamage);
|
||||
|
||||
|
@ -1234,7 +1234,7 @@ static void proj_ImpactFunc( PROJECTILE *psObj )
|
|||
{
|
||||
updateMultiStatsDamage(psObj->psSource->player, psCurr->player, damage);
|
||||
}
|
||||
int relativeDamage = objectDamage(psCurr, damage, psStats->weaponClass, psStats->weaponSubClass, psObj->time);
|
||||
int relativeDamage = objectDamage(psCurr, damage, psStats->weaponClass, psStats->weaponSubClass, psObj->time, false);
|
||||
proj_UpdateKills(psObj, relativeDamage);
|
||||
}
|
||||
}
|
||||
|
@ -1383,32 +1383,16 @@ static void proj_checkBurnDamage(PROJECTILE *psProj)
|
|||
continue; // Can't destroy oil wells.
|
||||
}
|
||||
|
||||
/* The object is in the fire */
|
||||
psCurr->inFire |= IN_FIRE;
|
||||
|
||||
if (psCurr->burnStart == 0 || (psCurr->inFire & BURNING) != 0)
|
||||
if (psCurr->burnStart != gameTime)
|
||||
{
|
||||
/* This is the first turn the object is in the fire */
|
||||
psCurr->burnStart = gameTime;
|
||||
psCurr->burnDamage = 0;
|
||||
psCurr->burnDamage = 0; // Reset burn damage done this tick.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate how much damage should have been done up till now.
|
||||
unsigned damageSoFar = (gameTime - psCurr->burnStart) * weaponIncenDamage(psStats,psProj->player) / GAME_TICKS_PER_SEC;
|
||||
int damageToDo = damageSoFar - psCurr->burnDamage;
|
||||
if (damageToDo > 0)
|
||||
{
|
||||
int32_t relativeDamage;
|
||||
debug(LOG_NEVER, "Burn damage of %d to object %d, player %d\n",
|
||||
damageToDo, psCurr->id, psCurr->player);
|
||||
unsigned damageRate = weaponIncenDamage(psStats,psProj->player);
|
||||
debug(LOG_NEVER, "Burn damage of %d per second to object %d, player %d\n", damageRate, psCurr->id, psCurr->player);
|
||||
|
||||
relativeDamage = objectDamage(psCurr, damageToDo, psStats->weaponClass, psStats->weaponSubClass, gameTime - deltaGameTime/2);
|
||||
psCurr->burnDamage += damageToDo;
|
||||
proj_UpdateKills(psProj, relativeDamage);
|
||||
}
|
||||
// The damage could be negative if the object is being burnt by another fire with a higher burn damage.
|
||||
}
|
||||
int relativeDamage = objectDamage(psCurr, damageRate, psStats->weaponClass, psStats->weaponSubClass, gameTime - deltaGameTime/2, true);
|
||||
proj_UpdateKills(psProj, relativeDamage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1536,20 +1520,20 @@ UDWORD calcDamage(UDWORD baseDamage, WEAPON_EFFECT weaponEffect, BASE_OBJECT *ps
|
|||
* multiplied by -1, resulting in a negative number. Killed features do not
|
||||
* result in negative numbers.
|
||||
*/
|
||||
static int32_t objectDamage(BASE_OBJECT *psObj, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime)
|
||||
static int32_t objectDamage(BASE_OBJECT *psObj, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime, bool isDamagePerSecond)
|
||||
{
|
||||
switch (psObj->type)
|
||||
{
|
||||
case OBJ_DROID:
|
||||
return droidDamage((DROID *)psObj, damage, weaponClass, weaponSubClass, impactTime);
|
||||
return droidDamage((DROID *)psObj, damage, weaponClass, weaponSubClass, impactTime, isDamagePerSecond);
|
||||
break;
|
||||
|
||||
case OBJ_STRUCTURE:
|
||||
return structureDamage((STRUCTURE *)psObj, damage, weaponClass, weaponSubClass, impactTime);
|
||||
return structureDamage((STRUCTURE *)psObj, damage, weaponClass, weaponSubClass, impactTime, isDamagePerSecond);
|
||||
break;
|
||||
|
||||
case OBJ_FEATURE:
|
||||
return featureDamage((FEATURE *)psObj, damage, weaponClass, weaponSubClass, impactTime);
|
||||
return featureDamage((FEATURE *)psObj, damage, weaponClass, weaponSubClass, impactTime, isDamagePerSecond);
|
||||
break;
|
||||
|
||||
case OBJ_PROJECTILE:
|
||||
|
|
|
@ -38,8 +38,6 @@ extern BASE_OBJECT *g_pProjLastAttacker; ///< The last unit that did damage - us
|
|||
#define PROJ_MAX_PITCH 45
|
||||
#define PROJ_ULTIMATE_PITCH 80
|
||||
|
||||
#define IN_FIRE 0x01 ///< Whether an object is in a fire.
|
||||
#define BURNING 0x02 ///< Whether an object has just left the fire, but is still burning.
|
||||
#define BURN_TIME 10000 ///< How long an object burns for after leaving a fire.
|
||||
#define BURN_DAMAGE 15 ///< How much damaga a second an object takes when it is burning.
|
||||
#define ACC_GRAVITY 1000 ///< Downward force against projectiles.
|
||||
|
|
|
@ -717,7 +717,7 @@ void handleAbandonedStructures()
|
|||
* \param weaponSubClass the subclass of the weapon that deals the damage
|
||||
* \return < 0 when the dealt damage destroys the structure, > 0 when the structure survives
|
||||
*/
|
||||
int32_t structureDamage(STRUCTURE *psStructure, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime)
|
||||
int32_t structureDamage(STRUCTURE *psStructure, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime, bool isDamagePerSecond)
|
||||
{
|
||||
int32_t relativeDamage;
|
||||
|
||||
|
@ -726,7 +726,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, psStructure->armour[weaponClass], damage);
|
||||
|
||||
relativeDamage = objDamage(psStructure, damage, structureBody(psStructure), weaponClass, weaponSubClass);
|
||||
relativeDamage = objDamage(psStructure, damage, structureBody(psStructure), weaponClass, weaponSubClass, isDamagePerSecond);
|
||||
|
||||
// If the shell did sufficient damage to destroy the structure
|
||||
if (relativeDamage < 0)
|
||||
|
@ -1473,7 +1473,6 @@ STRUCTURE* buildStructureDir(STRUCTURE_STATS *pStructureType, UDWORD x, UDWORD y
|
|||
psBuilding->targetOrigin[i] = ORIGIN_UNKNOWN;
|
||||
}
|
||||
|
||||
psBuilding->inFire = 0;
|
||||
psBuilding->burnStart = 0;
|
||||
psBuilding->burnDamage = 0;
|
||||
|
||||
|
@ -3679,16 +3678,12 @@ void structureUpdate(STRUCTURE *psBuilding, bool mission)
|
|||
}
|
||||
|
||||
/* Update the fire damage data */
|
||||
if (psBuilding->inFire & IN_FIRE)
|
||||
if (psBuilding->burnStart != 0 && psBuilding->burnStart != gameTime - deltaGameTime) // -deltaGameTime, since projectiles are updated after structures.
|
||||
{
|
||||
/* Still in a fire, reset the fire flag to see if we get out this turn */
|
||||
psBuilding->inFire = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The fire flag has not been set so we must be out of the fire */
|
||||
// The burnStart has been set, but is not from the previous tick, so we must be out of the fire.
|
||||
psBuilding->burnDamage = 0; // Reset burn damage done this tick.
|
||||
// Finished burning.
|
||||
psBuilding->burnStart = 0;
|
||||
psBuilding->burnDamage = 0;
|
||||
}
|
||||
|
||||
//check the resistance level of the structure
|
||||
|
|
|
@ -112,7 +112,7 @@ extern bool structureStatsShutDown(void);
|
|||
|
||||
int requestOpenGate(STRUCTURE *psStructure);
|
||||
|
||||
int32_t structureDamage(STRUCTURE *psStructure, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime);
|
||||
int32_t structureDamage(STRUCTURE *psStructure, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime, bool isDamagePerSecond);
|
||||
extern void structureBuild(STRUCTURE *psStructure, DROID *psDroid, int buildPoints, int buildRate = 1);
|
||||
extern void structureDemolish(STRUCTURE *psStructure, DROID *psDroid, int buildPoints);
|
||||
extern bool structureRepair(STRUCTURE *psStruct, DROID *psDroid, int buildPoints);
|
||||
|
|
Loading…
Reference in New Issue