Skip to content

Commit

Permalink
Render droid until the exact time the projectile hits and render expl…
Browse files Browse the repository at this point in the history
…osion effects at that time.

Or in the case of multiple projectiles hitting, render until the last projectile in the projectile
list hits (which might not have been the impact with the latest gameTime).
  • Loading branch information
Cyp committed Dec 28, 2011
1 parent 0610378 commit cb9504c
Show file tree
Hide file tree
Showing 18 changed files with 84 additions and 79 deletions.
2 changes: 1 addition & 1 deletion src/action.cpp
Expand Up @@ -1942,7 +1942,7 @@ void actionUpdateDroid(DROID *psDroid)
else
{
debug(LOG_DEATH, "Droid %d destructed", (int)psDroid->id);
destroyDroid(psDroid);
destroyDroid(psDroid, psDroid->actionStarted + ACTION_DESTRUCT_TIME);
}
}
break;
Expand Down
4 changes: 2 additions & 2 deletions src/component.cpp
Expand Up @@ -1052,7 +1052,7 @@ void displayComponentObject(DROID *psDroid)
}


void destroyFXDroid(DROID *psDroid)
void destroyFXDroid(DROID *psDroid, unsigned impactTime)
{
for (int i = 0; i < 5; ++i)
{
Expand Down Expand Up @@ -1114,7 +1114,7 @@ void destroyFXDroid(DROID *psDroid)
}
// Tell the effect system that it needs to use this player's color for the next effect
SetEffectForPlayer(psDroid->player);
addEffect(&pos, EFFECT_GRAVITON, GRAVITON_TYPE_EMITTING_DR, true, psImd, getPlayerColour(psDroid->player), gameTime - deltaGameTime);
addEffect(&pos, EFFECT_GRAVITON, GRAVITON_TYPE_EMITTING_DR, true, psImd, getPlayerColour(psDroid->player), impactTime);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/component.h
Expand Up @@ -66,7 +66,7 @@ void displayComponentObject(DROID *psDroid);
void compPersonToBits(DROID *psDroid);

SDWORD rescaleButtonObject(SDWORD radius, SDWORD baseScale,SDWORD baseRadius);
void destroyFXDroid(DROID *psDroid);
void destroyFXDroid(DROID *psDroid, unsigned impactTime);

/* Pass in the stats you're interested in and the COMPONENT - double reference, but works. NOTE: Unused!*/
#define PART_IMD(STATS,DROID,COMPONENT,PLAYER) (STATS[DROID->asBits[COMPONENT].nStat].pIMD)
Expand Down
42 changes: 23 additions & 19 deletions src/display3d.cpp
Expand Up @@ -1389,22 +1389,22 @@ void renderAnimComponent( const COMPONENT_OBJECT *psObj )
/// Draw the buildings
void displayStaticObjects( void )
{
STRUCTURE *psStructure;
UDWORD clan;
UDWORD test = 0;
ANIM_OBJECT *psAnimObj;

// to solve the flickering edges of baseplates
pie_SetDepthOffset(-1.0f);

/* Go through all the players */
for (clan = 0; clan < MAX_PLAYERS; clan++)
for (unsigned player = 0; player <= MAX_PLAYERS; ++player)
{
BASE_OBJECT *list = player < MAX_PLAYERS? apsStructLists[player] : psDestroyedObj;

/* Now go all buildings for that player */
for(psStructure = apsStructLists[clan]; psStructure != NULL;
psStructure = psStructure->psNext)
for (; list != NULL; list = list->psNext)
if (list->type == OBJ_STRUCTURE && (list->died == 0 || list->died > graphicsTime))
{
test++;
STRUCTURE *psStructure = castStructure(list);

/* Worth rendering the structure? */
if(clipXY(psStructure->pos.x,psStructure->pos.y))
{
Expand Down Expand Up @@ -1659,22 +1659,24 @@ void displayDelivPoints(void)
/// Draw the features
void displayFeatures( void )
{
FEATURE *psFeature;
UDWORD clan;

/* player can only be 0 for the features */
clan = 0;
// player can only be 0 for the features.
for (unsigned player = 0; player <= 1; ++player)
{
BASE_OBJECT *list = player < 1? apsFeatureLists[player] : psDestroyedObj;

/* Go through all the features */
for(psFeature = apsFeatureLists[clan]; psFeature != NULL;
psFeature = psFeature->psNext)
for (; list != NULL; list = list->psNext)
if (list->type == OBJ_FEATURE && (list->died == 0 || list->died > graphicsTime))
{
FEATURE *psFeature = castFeature(list);

/* Is the feature worth rendering? */
if(clipXY(psFeature->pos.x,psFeature->pos.y))
{
renderFeature(psFeature);
}
}
}
}

/// Draw the Proximity messages for the *SELECTED PLAYER ONLY*
Expand Down Expand Up @@ -1760,16 +1762,18 @@ static void displayAnimation( ANIM_OBJECT * psAnimObj, bool bHoldOnFirstFrame )
/// Draw the droids
void displayDynamicObjects( void )
{
DROID *psDroid;
ANIM_OBJECT *psAnimObj;
UDWORD clan;

/* Need to go through all the droid lists */
for(clan = 0; clan < MAX_PLAYERS; clan++)
for (unsigned player = 0; player <= MAX_PLAYERS; ++player)
{
for(psDroid = apsDroidLists[clan]; psDroid != NULL;
psDroid = psDroid->psNext)
BASE_OBJECT *list = player < MAX_PLAYERS? apsDroidLists[player] : psDestroyedObj;

for (; list != NULL; list = list->psNext)
if (list->type == OBJ_DROID && (list->died == 0 || list->died > graphicsTime))
{
DROID *psDroid = castDroid(list);

/* Find out whether the droid is worth rendering */
if(clipXY(psDroid->pos.x,psDroid->pos.y))
{
Expand Down
20 changes: 10 additions & 10 deletions src/droid.cpp
Expand Up @@ -151,7 +151,7 @@ bool droidInit(void)
*
* NOTE: This function will damage but _never_ destroy transports when in single player (campaign) mode
*/
int32_t droidDamage(DROID *psDroid, uint32_t damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass)
int32_t droidDamage(DROID *psDroid, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime)
{
int32_t relativeDamage;

Expand Down Expand Up @@ -224,12 +224,12 @@ int32_t droidDamage(DROID *psDroid, uint32_t damage, WEAPON_CLASS weaponClass, W
if (bMultiPlayer && !bMultiMessages)
{
bMultiMessages = true;
destroyDroid(psDroid);
destroyDroid(psDroid, impactTime);
bMultiMessages = false;
}
else
{
destroyDroid(psDroid);
destroyDroid(psDroid, impactTime);
}
}
}
Expand Down Expand Up @@ -509,7 +509,7 @@ void removeDroidBase(DROID *psDel)
killDroid(psDel);
}

static void removeDroidFX(DROID *psDel)
static void removeDroidFX(DROID *psDel, unsigned impactTime)
{
Vector3i pos;

Expand Down Expand Up @@ -537,16 +537,16 @@ static void removeDroidFX(DROID *psDel)
}
else if (psDel->visible[selectedPlayer])
{
destroyFXDroid(psDel);
destroyFXDroid(psDel, impactTime);
pos.x = psDel->pos.x;
pos.z = psDel->pos.y;
pos.y = psDel->pos.z;
addEffect(&pos, EFFECT_DESTRUCTION, DESTRUCTION_TYPE_DROID, false, NULL, 0, gameTime - deltaGameTime);
addEffect(&pos, EFFECT_DESTRUCTION, DESTRUCTION_TYPE_DROID, false, NULL, 0, impactTime);
audio_PlayStaticTrack( psDel->pos.x, psDel->pos.y, ID_SOUND_EXPLOSION );
}
}

void destroyDroid(DROID *psDel)
void destroyDroid(DROID *psDel, unsigned impactTime)
{
if (psDel->lastHitWeapon == WSC_LAS_SAT) // darken tile if lassat.
{
Expand All @@ -568,8 +568,9 @@ void destroyDroid(DROID *psDel)
}
}

removeDroidFX(psDel);
removeDroidFX(psDel, impactTime);
removeDroidBase(psDel);
psDel->died = impactTime;
return;
}

Expand Down Expand Up @@ -865,8 +866,7 @@ void droidUpdate(DROID *psDroid)
{
psDroid->burnDamage += damageToDo;

//just assume the burn damage is from FRONT
droidDamage(psDroid, damageToDo, WC_HEAT, WSC_FLAME);
droidDamage(psDroid, damageToDo, WC_HEAT, WSC_FLAME, gameTime - deltaGameTime/2);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/droid.h
Expand Up @@ -128,7 +128,7 @@ extern UDWORD calcTemplatePower(DROID_TEMPLATE *psTemplate);
bool idfDroid(DROID *psDroid);

/* Do damage to a droid */
int32_t droidDamage(DROID *psDroid, uint32_t damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass);
int32_t droidDamage(DROID *psDroid, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime);

/* The main update routine for all droids */
extern void droidUpdate(DROID *psDroid);
Expand Down Expand Up @@ -173,7 +173,7 @@ extern bool droidUpdateRestore( DROID *psDroid );
extern void recycleDroid(DROID *psDel);

/* Remove a droid and free it's memory */
extern void destroyDroid(DROID *psDel);
void destroyDroid(DROID *psDel, unsigned impactTime);

/* Same as destroy droid except no graphical effects */
extern void vanishDroid(DROID *psDel);
Expand Down
16 changes: 8 additions & 8 deletions src/feature.cpp
Expand Up @@ -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, UDWORD damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass)
int32_t featureDamage(FEATURE *psFeature, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime)
{
int32_t relativeDamage;

Expand All @@ -180,7 +180,7 @@ int32_t featureDamage(FEATURE *psFeature, UDWORD damage, WEAPON_CLASS weaponClas
if (relativeDamage < 0)
{
debug(LOG_ATTACK, "feature (id %d) DESTROYED", psFeature->id);
destroyFeature(psFeature);
destroyFeature(psFeature, impactTime);
return relativeDamage * -1;
}
else
Expand Down Expand Up @@ -365,10 +365,9 @@ bool removeFeature(FEATURE *psDel)
ASSERT_OR_RETURN(false, psDel != NULL, "Invalid feature pointer");
ASSERT_OR_RETURN(false, !psDel->died, "Feature already dead");

if(bMultiMessages && !ingame.localJoiningInProgress)
if (bMultiMessages && !ingame.localJoiningInProgress && !isInSync())
{
SendDestroyFeature(psDel); // inform other players of destruction
return true; // Wait for our message before really destroying the feature.
}

//remove from the map data
Expand Down Expand Up @@ -423,7 +422,7 @@ bool removeFeature(FEATURE *psDel)
}

/* Remove a Feature and free it's memory */
bool destroyFeature(FEATURE *psDel)
bool destroyFeature(FEATURE *psDel, unsigned impactTime)
{
UDWORD widthScatter,breadthScatter,heightScatter, i;
EFFECT_TYPE explosionSize;
Expand Down Expand Up @@ -457,15 +456,15 @@ bool destroyFeature(FEATURE *psDel)
pos.x = psDel->pos.x + widthScatter - rand()%(2*widthScatter);
pos.z = psDel->pos.y + breadthScatter - rand()%(2*breadthScatter);
pos.y = psDel->pos.z + 32 + rand()%heightScatter;
addEffect(&pos, EFFECT_EXPLOSION, explosionSize, false, NULL, 0, gameTime - deltaGameTime);
addEffect(&pos, EFFECT_EXPLOSION, explosionSize, false, NULL, 0, impactTime);
}

if(psDel->psStats->subType == FEAT_SKYSCRAPER)
{
pos.x = psDel->pos.x;
pos.z = psDel->pos.y;
pos.y = psDel->pos.z;
addEffect(&pos, EFFECT_DESTRUCTION, DESTRUCTION_TYPE_SKYSCRAPER, true, psDel->sDisplay.imd, 0, gameTime - deltaGameTime);
addEffect(&pos, EFFECT_DESTRUCTION, DESTRUCTION_TYPE_SKYSCRAPER, true, psDel->sDisplay.imd, 0, impactTime);
initPerimeterSmoke(psDel->sDisplay.imd, pos);

shakeStart();
Expand All @@ -475,7 +474,7 @@ bool destroyFeature(FEATURE *psDel)
pos.x = psDel->pos.x;
pos.z = psDel->pos.y;
pos.y = map_Height(pos.x,pos.z);
addEffect(&pos, EFFECT_DESTRUCTION, DESTRUCTION_TYPE_FEATURE, false, NULL, 0, gameTime - deltaGameTime);
addEffect(&pos, EFFECT_DESTRUCTION, DESTRUCTION_TYPE_FEATURE, false, NULL, 0, impactTime);

//play sound
// ffs gj
Expand Down Expand Up @@ -520,6 +519,7 @@ bool destroyFeature(FEATURE *psDel)
}

removeFeature(psDel);
psDel->died = impactTime;
return true;
}

Expand Down
4 changes: 2 additions & 2 deletions src/feature.h
Expand Up @@ -49,12 +49,12 @@ extern void featureUpdate(FEATURE *psFeat);
extern bool removeFeature(FEATURE *psDel);

/* Remove a Feature and free it's memory */
extern bool destroyFeature(FEATURE *psDel);
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, UDWORD damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass);
int32_t featureDamage(FEATURE *psFeature, unsigned damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, unsigned impactTime);

extern void featureInitVars(void);

Expand Down
4 changes: 2 additions & 2 deletions src/move.cpp
Expand Up @@ -732,7 +732,7 @@ static void moveCheckSquished(DROID *psDroid, int32_t emx, int32_t emy)
if ((psDroid->player != psObj->player) && !aiCheckAlliances(psDroid->player, psObj->player))
{
// run over a bloke - kill him
destroyDroid((DROID *)psObj);
destroyDroid((DROID *)psObj, gameTime);
scoreUpdateVar(WD_BARBARIANS_MOWED_DOWN);
}
}
Expand Down Expand Up @@ -1630,7 +1630,7 @@ static void moveUpdateDroidPos(DROID *psDroid, int32_t dx, int32_t dy)
if (psDroid->droidType != DROID_TRANSPORTER)
{
/* dreadful last-ditch crash-avoiding hack - sort this! - GJ */
destroyDroid( psDroid );
destroyDroid(psDroid, gameTime);
return;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/multibot.cpp
Expand Up @@ -804,7 +804,7 @@ bool recvDestroyDroid(NETQUEUE queue)
{
turnOffMultiMsg(true);
debug(LOG_DEATH, "Killing droid %d on request from player %d - huh?", psDroid->id, queue.index);
destroyDroid(psDroid);
destroyDroid(psDroid, gameTime);
turnOffMultiMsg(false);
}
else
Expand Down
4 changes: 2 additions & 2 deletions src/multijoin.cpp
Expand Up @@ -144,7 +144,7 @@ void clearPlayer(UDWORD player,bool quietly)
}
else // show effects
{
destroyDroid(apsDroidLists[player]);
destroyDroid(apsDroidLists[player], gameTime);
}
}

Expand All @@ -161,7 +161,7 @@ void clearPlayer(UDWORD player,bool quietly)
}
else // show effects
{
destroyStruct(psStruct);
destroyStruct(psStruct, gameTime);
}

psStruct = psNext;
Expand Down
2 changes: 1 addition & 1 deletion src/multistruct.cpp
Expand Up @@ -226,7 +226,7 @@ bool recvDestroyStructure(NETQUEUE queue)
{
turnOffMultiMsg(true);
// Remove the struct from remote players machine
destroyStruct(psStruct);
destroyStruct(psStruct, gameTime);
turnOffMultiMsg(false);
// NOTE: I do not think this should be here!
technologyGiveAway(psStruct);
Expand Down
4 changes: 2 additions & 2 deletions src/objmem.cpp
Expand Up @@ -143,7 +143,7 @@ void objmemUpdate(void)
were destroyed before this turn */

/* First remove the objects from the start of the list */
while (psDestroyedObj != NULL && psDestroyedObj->died != gameTime)
while (psDestroyedObj != NULL && psDestroyedObj->died < gameTime - deltaGameTime)
{
psNext = psDestroyedObj->psNext;
objmemDestroy(psDestroyedObj);
Expand All @@ -155,7 +155,7 @@ void objmemUpdate(void)
for(psCurr = psPrev = psDestroyedObj; psCurr != NULL; psCurr = psNext)
{
psNext = psCurr->psNext;
if (psCurr->died != gameTime)
if (psCurr->died < gameTime - deltaGameTime)
{
objmemDestroy(psCurr);

Expand Down
2 changes: 1 addition & 1 deletion src/order.cpp
Expand Up @@ -943,7 +943,7 @@ void orderUpdateDroid(DROID *psDroid)
if (psDroid->actionStarted + RUN_BURN_TIME < gameTime)
{
debug(LOG_DEATH, "orderUpdateDroid: Droid %d burned to death", psDroid->id); // why is this an order?
destroyDroid( psDroid );
destroyDroid(psDroid, psDroid->actionStarted + RUN_BURN_TIME);
}
break;
case DORDER_RUN:
Expand Down

0 comments on commit cb9504c

Please sign in to comment.