Skip to content
GitLab
  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • EDuke32 EDuke32
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 97
    • Issues 97
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 13
    • Merge requests 13
  • Deployments
    • Deployments
    • Releases
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • Repository
  • Activity
  • Graph
  • Create a new issue
  • Commits
  • Issue Boards
Collapse sidebar
  • Richard Gobeille
  • EDuke32EDuke32
  • Issues
  • #135
Closed
Open
Created Nov 05, 2020 by Dino Bollinger@dibollingerDeveloper

Duke3D: Ordering Issue with PROJECTILE_RPG_IMPACT and DAMAGESPRITE events

The following block of code is present in actors.cpp, inside the function ACTOR_STATIC void Proj_MoveCustom(int const spriteNum), starting at line 3109:

A_DamageObject(otherSprite, spriteNum);

...

if (pProj->workslike & PROJECTILE_RPG_IMPACT)
{
   actor[otherSprite].owner  = pSprite->owner;
   actor[otherSprite].picnum = pSprite->picnum;

   if (pProj->workslike & PROJECTILE_RPG_IMPACT_DAMAGE)
      actor[otherSprite].extra += pProj->extra;

   A_DoProjectileEffects(spriteNum, &davect, 0);

   if (!(pProj->workslike & PROJECTILE_FORCEIMPACT))
   {
       A_DeleteSprite(spriteNum);
       return;
   }
}

Note that in the following: actor[otherSprite].owner == htowner, actor[otherSprite].picnum == htpicnum and actor[otherSprite].extra == htextra.

Notice that A_DamageObject() handles projectile damage and calls both EVENT_DAMAGESPRITE as well as EVENT_POSTDAMAGESPRITE respectively at the start and the end of the function. The former event is supposed to be executed before the damage is added to the htextra struct member (and also, before htowner and htpicnum are set), while the latter event is supposed to be executed after these members have been updated.

The above block of code however is executed for any custom projectile that has the PROJECTILE_RPG_IMPACT flag, and breaks the assumptions made for EVENT_POSTDAMAGESPRITE. Namely, the htowner as well as htpicnum members are updated a second time, thus preventing them from being changed inside EVENT_POSTDAMAGESPRITE, and if the flag PROJECTILE_RPG_IMPACT_DAMAGE is also given, then the damage is incremented after the event, meaning that EVENT_POSTDAMAGESPRITE does not have access to the full damage the projectile does to the enemy.

As a result, this block of code bypasses any changes made to the overall damage in EVENT_DAMAGESPRITE. For example, if we tried to code different damage resistances for certain enemy types, PROJECTILE_RPG_IMPACT_DAMAGE would bypass this resistance and apply the full damage, regardless of what is done in the CON code.

However, if we were to reorder this code such that A_DamageObject() is executed only after the PROJECTILE_RPG_IMPACT block, then we break the assumption about EVENT_DAMAGESPRITE instead, as some damage has already been added to htextra.

Assignee
Assign to
Time tracking