Optimize A_RadiusDamage()

git-svn-id: https://svn.eduke32.com/eduke32@6796 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2018-04-02 22:00:33 +00:00
parent 3f47f2fccb
commit f978ba0d07

View file

@ -104,33 +104,23 @@ static FORCE_INLINE int32_t G_WallSpriteDist(uwalltype const * const wal, usprit
void A_RadiusDamage(int spriteNum, int blastRadius, int dmg1, int dmg2, int dmg3, int dmg4) void A_RadiusDamage(int spriteNum, int blastRadius, int dmg1, int dmg2, int dmg3, int dmg4)
{ {
int32_t d, q;
uspritetype const *const pSprite = (uspritetype *)&sprite[spriteNum];
static const int32_t statnumList[] = {
STAT_DEFAULT, STAT_ACTOR, STAT_STANDABLE,
STAT_PLAYER, STAT_FALLER, STAT_ZOMBIEACTOR, STAT_MISC
};
// XXX: accesses to 'sectorlist' potentially unaligned
int16_t *const sectorList = (int16_t *)tempbuf;
const int32_t maxSectors = sizeof(tempbuf)/sizeof(int16_t);
ud.returnvar[0] = blastRadius; // Allow checking for radius damage in EVENT_DAMAGE(SPRITE/WALL/FLOOR/CEILING) events. ud.returnvar[0] = blastRadius; // Allow checking for radius damage in EVENT_DAMAGE(SPRITE/WALL/FLOOR/CEILING) events.
ud.returnvar[1] = dmg1; ud.returnvar[1] = dmg1;
ud.returnvar[2] = dmg2; ud.returnvar[2] = dmg2;
ud.returnvar[3] = dmg3; ud.returnvar[3] = dmg3;
ud.returnvar[4] = dmg4; ud.returnvar[4] = dmg4;
if (pSprite->picnum == RPG && pSprite->xrepeat < 11) uspritetype const *const pSprite = (uspritetype *)&sprite[spriteNum];
goto SKIPWALLCHECK;
if (pSprite->picnum != SHRINKSPARK)
{
int32_t sectorCount = 0; int32_t sectorCount = 0;
int32_t numSectors = 1; int32_t numSectors = 1;
sectorList[0] = pSprite->sectnum; #ifndef EDUKE32_STANDALONE
if ((pSprite->picnum == RPG && pSprite->xrepeat < 11) || pSprite->picnum == SHRINKSPARK)
goto SKIPWALLCHECK;
#endif
int16_t sectorList[64] = { pSprite->sectnum };
do do
{ {
@ -150,53 +140,55 @@ void A_RadiusDamage(int spriteNum, int blastRadius, int dmg1, int dmg2, int dmg3
Sect_DamageFloor_Internal(spriteNum, sectorNum); Sect_DamageFloor_Internal(spriteNum, sectorNum);
} }
uwalltype const *pWall; native_t w = startWall;
int w = startWall;
for (pWall=(uwalltype *)&wall[startWall]; w<endWall; w++,pWall++) for (uwalltype const *pWall = (uwalltype *)&wall[startWall]; w < endWall; w++, pWall++)
{ {
if (G_WallSpriteDist(pWall, pSprite) < blastRadius) if (G_WallSpriteDist(pWall, pSprite) >= blastRadius)
{ continue;
int16_t damageSector = pSprite->sectnum;
int const nextSector = pWall->nextsector; int const nextSector = pWall->nextsector;
if (nextSector >= 0) if (nextSector >= 0)
{ {
int32_t dasect2; native_t otherSector = 0;
for (dasect2=numSectors-1; dasect2>=0; dasect2--) for (; otherSector < numSectors; ++otherSector)
if (sectorList[dasect2] == nextSector) if (sectorList[otherSector] == nextSector)
break; break;
if (dasect2 < 0) if (otherSector == numSectors)
{ {
if (numSectors == maxSectors) if (numSectors == ARRAY_SIZE(sectorList))
goto SKIPWALLCHECK; // prevent oob access of 'sectorlist' goto SKIPWALLCHECK; // prevent oob access of 'sectorlist'
sectorList[numSectors++] = nextSector; sectorList[numSectors++] = nextSector;
} }
} }
vec2_t const vect = { (((pWall->x + wall[pWall->point2].x) >> 1) + pSprite->x) >> 1, int16_t damageSector = (nextSector >= 0) ? wall[wall[w].nextwall].nextsector : sectorofwall(w);
(((pWall->y + wall[pWall->point2].y) >> 1) + pSprite->y) >> 1 }; vec3_t const vect = { (((pWall->x + wall[pWall->point2].x) >> 1) + pSprite->x) >> 1,
(((pWall->y + wall[pWall->point2].y) >> 1) + pSprite->y) >> 1, pSprite->z };
updatesector(vect.x, vect.y, &damageSector); updatesector(vect.x, vect.y, &damageSector);
if (damageSector >= 0 && cansee(vect.x, vect.y, pSprite->z, damageSector, if (damageSector >= 0 && cansee(vect.x, vect.y, pSprite->z, damageSector, pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum))
pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum)) A_DamageWall_Internal(spriteNum, w, &vect, pSprite->picnum);
{
vec3_t const tmpvect = { pWall->x, pWall->y, pSprite->z };
A_DamageWall_Internal(spriteNum, w, &tmpvect, pSprite->picnum);
}
}
} }
} }
while (sectorCount < numSectors); while (sectorCount < numSectors);
}
SKIPWALLCHECK: SKIPWALLCHECK:
q = -ZOFFSET2 + (krand()&(ZOFFSET5-1)); // this is really weird
int32_t const zRand = -ZOFFSET2 + (krand()&(ZOFFSET5-1));
for (bssize_t stati=0; stati < ARRAY_SSIZE(statnumList); stati++) static const uint8_t statnumList [] ={
STAT_DEFAULT, STAT_ACTOR, STAT_STANDABLE,
STAT_PLAYER, STAT_FALLER, STAT_ZOMBIEACTOR, STAT_MISC
};
for (native_t stati=0; stati < ARRAY_SSIZE(statnumList); stati++)
{ {
int32_t otherSprite = headspritestat[statnumList[stati]]; int32_t otherSprite = headspritestat[statnumList[stati]];
@ -206,76 +198,74 @@ SKIPWALLCHECK:
spritetype *const pOther = &sprite[otherSprite]; spritetype *const pOther = &sprite[otherSprite];
// DEFAULT, ZOMBIEACTOR, MISC // DEFAULT, ZOMBIEACTOR, MISC
if (stati == 0 || stati >= 5 || AFLAMABLE(pOther->picnum)) if (statnumList[stati] == STAT_DEFAULT || statnumList[stati] == STAT_ZOMBIEACTOR || statnumList[stati] == STAT_MISC || AFLAMABLE(pOther->picnum))
{ {
#ifndef EDUKE32_STANDALONE
if (pSprite->picnum != SHRINKSPARK || (pOther->cstat&257)) if (pSprite->picnum != SHRINKSPARK || (pOther->cstat&257))
#endif
{
if (dist(pSprite, pOther) < blastRadius) if (dist(pSprite, pOther) < blastRadius)
{ {
if (A_CheckEnemySprite(pOther) && !cansee(pOther->x, pOther->y,pOther->z+q, pOther->sectnum, pSprite->x, pSprite->y, pSprite->z+q, pSprite->sectnum)) if (A_CheckEnemySprite(pOther) && !cansee(pOther->x, pOther->y, pOther->z+zRand, pOther->sectnum, pSprite->x, pSprite->y, pSprite->z+zRand, pSprite->sectnum))
goto next_sprite; goto next_sprite;
A_DamageObject_Internal(otherSprite, spriteNum); A_DamageObject_Internal(otherSprite, spriteNum);
} }
} }
else if (pOther->extra >= 0 && (uspritetype *)pOther != pSprite &&
(pOther->picnum == TRIPBOMB || A_CheckEnemySprite(pOther) || pOther->picnum == QUEBALL ||
pOther->picnum == STRIPEBALL || (pOther->cstat & 257) || pOther->picnum == DUKELYINGDEAD))
{
if ((pSprite->picnum == SHRINKSPARK && pOther->picnum != SHARK &&
(otherSprite == pSprite->owner || pOther->xrepeat < 24)) ||
(pSprite->picnum == MORTER && otherSprite == pSprite->owner))
{
otherSprite = nextOther;
continue;
} }
else if (pOther->extra >= 0 && (uspritetype *)pOther != pSprite && ((pOther->cstat & 257) ||
if (pOther->picnum == APLAYER) #ifndef EDUKE32_STANDALONE
pOther->z -= PHEIGHT; pOther->picnum == TRIPBOMB || pOther->picnum == QUEBALL || pOther->picnum == STRIPEBALL || pOther->picnum == DUKELYINGDEAD ||
#endif
d = dist(pSprite, pOther); A_CheckEnemySprite(pOther)))
if (pOther->picnum == APLAYER)
pOther->z += PHEIGHT;
if (d < blastRadius && cansee(pOther->x, pOther->y, pOther->z - ZOFFSET3, pOther->sectnum, pSprite->x,
pSprite->y, pSprite->z - ZOFFSET4, pSprite->sectnum))
{ {
#ifndef EDUKE32_STANDALONE
if ((pSprite->picnum == SHRINKSPARK && pOther->picnum != SHARK && (otherSprite == pSprite->owner || pOther->xrepeat < 24))
|| (pSprite->picnum == MORTER && otherSprite == pSprite->owner))
goto next_sprite;
#endif
int32_t const spriteDist = pOther->picnum == APLAYER
? sepdist(pSprite->x - pOther->x, pSprite->y - pOther->y, pSprite->z - (pOther->z - PHEIGHT))
: dist(pSprite, pOther);
if (spriteDist >= blastRadius || !cansee(pOther->x, pOther->y, pOther->z - ZOFFSET3, pOther->sectnum, pSprite->x,
pSprite->y, pSprite->z - ZOFFSET4, pSprite->sectnum))
goto next_sprite;
if (A_CheckSpriteFlags(otherSprite, SFLAG_DAMAGEEVENT)) if (A_CheckSpriteFlags(otherSprite, SFLAG_DAMAGEEVENT))
{ {
if (VM_OnEventWithReturn(EVENT_DAMAGESPRITE, spriteNum, -1, otherSprite) < 0) if (VM_OnEventWithReturn(EVENT_DAMAGESPRITE, spriteNum, -1, otherSprite) < 0)
goto next_sprite; goto next_sprite;
} }
actor[otherSprite].ang = getangle(pOther->x-pSprite->x,pOther->y-pSprite->y); actor_t & dmgActor = actor[otherSprite];
if (pSprite->picnum == RPG && pOther->extra > 0) dmgActor.ang = getangle(pOther->x - pSprite->x, pOther->y - pSprite->y);
actor[otherSprite].picnum = RPG;
else if (A_CheckSpriteFlags(spriteNum,SFLAG_PROJECTILE) && SpriteProjectile[spriteNum].workslike & PROJECTILE_RADIUS_PICNUM && pOther->extra > 0)
actor[otherSprite].picnum = pSprite->picnum;
else
{
if (pSprite->picnum == SHRINKSPARK)
actor[otherSprite].picnum = SHRINKSPARK;
else actor[otherSprite].picnum = RADIUSEXPLOSION;
}
if ((pOther->extra > 0 && ((A_CheckSpriteFlags(spriteNum, SFLAG_PROJECTILE) && SpriteProjectile[spriteNum].workslike & PROJECTILE_RADIUS_PICNUM) || pSprite->picnum == RPG))
|| (pSprite->picnum == SHRINKSPARK))
dmgActor.picnum = pSprite->picnum;
else dmgActor.picnum = RADIUSEXPLOSION;
#ifndef EDUKE32_STANDALONE
if (pSprite->picnum != SHRINKSPARK) if (pSprite->picnum != SHRINKSPARK)
#endif
{ {
const int32_t k = blastRadius/3; int32_t const k = blastRadius/3;
if (d < k) if (spriteDist < k)
{ {
if (dmg4 == dmg3) dmg4++; if (dmg4 == dmg3) dmg4++;
actor[otherSprite].extra = dmg3 + (krand()%(dmg4-dmg3)); dmgActor.extra = dmg3 + (krand()%(dmg4-dmg3));
} }
else if (d < k*2) else if (spriteDist < k*2)
{ {
if (dmg3 == dmg2) dmg3++; if (dmg3 == dmg2) dmg3++;
actor[otherSprite].extra = dmg2 + (krand()%(dmg3-dmg2)); dmgActor.extra = dmg2 + (krand()%(dmg3-dmg2));
} }
else if (d < blastRadius) else if (spriteDist < blastRadius)
{ {
if (dmg2 == dmg1) dmg2++; if (dmg2 == dmg1) dmg2++;
actor[otherSprite].extra = dmg1 + (krand()%(dmg2-dmg1)); dmgActor.extra = dmg1 + (krand()%(dmg2-dmg1));
} }
if (!A_CheckSpriteFlags(otherSprite, SFLAG_NODAMAGEPUSH)) if (!A_CheckSpriteFlags(otherSprite, SFLAG_NODAMAGEPUSH))
@ -287,15 +277,32 @@ SKIPWALLCHECK:
if (A_CheckSpriteFlags(otherSprite, SFLAG_DAMAGEEVENT)) if (A_CheckSpriteFlags(otherSprite, SFLAG_DAMAGEEVENT))
VM_OnEventWithReturn(EVENT_POSTDAMAGESPRITE, spriteNum, -1, otherSprite); VM_OnEventWithReturn(EVENT_POSTDAMAGESPRITE, spriteNum, -1, otherSprite);
if (pOther->picnum == PODFEM1 || pOther->picnum == FEM1 || pOther->picnum == FEM2 || #ifndef EDUKE32_STANDALONE
pOther->picnum == FEM3 || pOther->picnum == FEM4 || pOther->picnum == FEM5 || switch (DYNAMICTILEMAP(pOther->picnum))
pOther->picnum == FEM6 || pOther->picnum == FEM7 || pOther->picnum == FEM8 || {
pOther->picnum == FEM9 || pOther->picnum == FEM10 || pOther->picnum == STATUE || case PODFEM1__STATIC:
pOther->picnum == STATUEFLASH || pOther->picnum == SPACEMARINE || pOther->picnum == QUEBALL || case FEM1__STATIC:
pOther->picnum == STRIPEBALL) case FEM2__STATIC:
A_DamageObject_Internal(otherSprite, spriteNum); case FEM3__STATIC:
case FEM4__STATIC:
case FEM5__STATIC:
case FEM6__STATIC:
case FEM7__STATIC:
case FEM8__STATIC:
case FEM9__STATIC:
case FEM10__STATIC:
case STATUE__STATIC:
case STATUEFLASH__STATIC:
case SPACEMARINE__STATIC:
case QUEBALL__STATIC:
case STRIPEBALL__STATIC: A_DamageObject_Internal(otherSprite, spriteNum);
default: break;
} }
else if (pSprite->extra == 0) actor[otherSprite].extra = 0; #endif
}
#ifndef EDUKE32_STANDALONE
else if (pSprite->extra == 0) dmgActor.extra = 0;
#endif
if (pOther->picnum != RADIUSEXPLOSION && if (pOther->picnum != RADIUSEXPLOSION &&
pSprite->owner >= 0 && sprite[pSprite->owner].statnum < MAXSTATUS) pSprite->owner >= 0 && sprite[pSprite->owner].statnum < MAXSTATUS)
@ -308,8 +315,7 @@ SKIPWALLCHECK:
G_ClearCameraView(pPlayer); G_ClearCameraView(pPlayer);
} }
actor[otherSprite].owner = pSprite->owner; dmgActor.owner = pSprite->owner;
}
} }
} }
next_sprite: next_sprite: