Clean up bullet code a bit

This commit is contained in:
nukeykt 2019-09-26 06:16:12 +09:00 committed by Christoph Oelckers
parent a1ce0830db
commit 83a4485140
3 changed files with 702 additions and 790 deletions

View file

@ -138,66 +138,6 @@ void BulletHitsSprite(Bullet *pBullet, short nBulletSprite, short nHitSprite, in
switch (pBullet->nType) switch (pBullet->nType)
{ {
case 0:
case 4:
case 5:
case 6:
case 7:
case 10:
case 11:
{
break;
}
case 14:
{
if (nStat > 107 || nStat == 98) {
return;
}
// else - fall through to below cases
}
case 1:
case 2:
case 8:
case 9:
case 12:
case 13:
case 15:
case 16:
{
// loc_29E59
if (!nStat || nStat > 98) {
break;
}
short nSprite = pBullet->nSprite;
if (nStat == 98)
{
short nAngle = sprite[nSprite].ang + 256;
int nRand = RandomSize(9);
sprite[nHitSprite].xvel = Sin((nAngle - nRand) + 512) * 2;
sprite[nHitSprite].yvel = Sin((nAngle - nRand)) * 2;
sprite[nHitSprite].zvel = (-(RandomSize(3) + 1)) << 8;
}
else
{
int xVel = sprite[nHitSprite].xvel;
int yVel = sprite[nHitSprite].yvel;
sprite[nHitSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 2;
sprite[nHitSprite].yvel = Sin(sprite[nSprite].ang) >> 2;
MoveCreature(nHitSprite);
sprite[nHitSprite].xvel = xVel;
sprite[nHitSprite].yvel = yVel;
}
break;
}
case 3: case 3:
{ {
if (nStat > 107 || nStat == 98) { if (nStat > 107 || nStat == 98) {
@ -216,6 +156,56 @@ void BulletHitsSprite(Bullet *pBullet, short nBulletSprite, short nHitSprite, in
return; return;
} }
case 14:
{
if (nStat > 107 || nStat == 98) {
return;
}
// else - fall through to below cases
fallthrough__;
}
case 1:
case 2:
case 8:
case 9:
case 12:
case 13:
case 15:
case 16:
{
// loc_29E59
if (!nStat || nStat > 98) {
break;
}
short nSprite = pBullet->nSprite;
spritetype *pSprite = &sprite[nSprite];
spritetype *pHitSprite = &sprite[nHitSprite];
if (nStat != 98)
{
int xVel = pHitSprite->xvel;
int yVel = pHitSprite->yvel;
pHitSprite->xvel = Cos(pSprite->ang) >> 2;
pHitSprite->yvel = Sin(pSprite->ang) >> 2;
MoveCreature(nHitSprite);
pHitSprite->xvel = xVel;
pHitSprite->yvel = yVel;
}
else
{
short nAngle = pSprite->ang - (RandomSize(9) - 256);
pHitSprite->xvel = Cos(nAngle) << 1;
pHitSprite->yvel = Sin(nAngle) << 1;
pHitSprite->zvel = (-(RandomSize(3) + 1)) << 8;
}
break;
}
default: default:
break; break;
@ -236,52 +226,31 @@ void BulletHitsSprite(Bullet *pBullet, short nBulletSprite, short nHitSprite, in
return; return;
} }
if (nStat < 98) switch (nStat)
{
if (nStat <= 0)
{ {
case 97:
break;
case 0:
case 98:
case 102:
case 141:
case 152:
BuildAnim(-1, 12, 0, x, y, z, nSector, 40, 0); BuildAnim(-1, 12, 0, x, y, z, nSector, 40, 0);
} break;
else if (nStat == 97) default:
{
return;
}
else
{
// BHS_B
BuildAnim(-1, 39, 0, x, y, z, nSector, 40, 0); BuildAnim(-1, 39, 0, x, y, z, nSector, 40, 0);
if (pBullet->nType > 2) if (pBullet->nType > 2)
{ {
BuildAnim(-1, pBulletInfo->field_C, 0, x, y, z, nSector, 40, pBulletInfo->nFlags); BuildAnim(-1, pBulletInfo->field_C, 0, x, y, z, nSector, 40, pBulletInfo->nFlags);
} }
} break;
return;
}
else
{
if (nStat == 98 || nStat == 141 || nStat == 152 || nStat == 102)
{
BuildAnim(-1, 12, 0, x, y, z, nSector, 40, 0);
}
else
{
// BHS_B
BuildAnim(-1, 39, 0, x, y, z, nSector, 40, 0);
if (pBullet->nType > 2)
{
BuildAnim(-1, pBulletInfo->field_C, 0, x, y, z, nSector, 40, pBulletInfo->nFlags);
}
}
return;
} }
} }
void BackUpBullet(int *x, int *y, short nAngle) void BackUpBullet(int *x, int *y, short nAngle)
{ {
*x -= Sin(nAngle + 512) >> 11; *x -= Cos(nAngle) >> 11;
*y -= Sin(nAngle) >> 11; *y -= Sin(nAngle) >> 11;
} }
@ -291,129 +260,114 @@ int MoveBullet(short nBullet)
short hitwall = -1; short hitwall = -1;
short hitsprite = -1; short hitsprite = -1;
short nType = BulletList[nBullet].nType; Bullet *pBullet = &BulletList[nBullet];
short nSprite = BulletList[nBullet].nSprite; short nType = pBullet->nType;
bulletInfo *pBulletInfo = &BulletInfo[nType];
int x = sprite[nSprite].x; short nSprite = BulletList[nBullet].nSprite;
int y = sprite[nSprite].y; spritetype *pSprite = &sprite[nSprite];
int z = sprite[nSprite].z; // ebx
short nSectFlag = SectFlag[sprite[nSprite].sectnum]; int x = pSprite->x;
int y = pSprite->y;
int z = pSprite->z; // ebx
short nSectFlag = SectFlag[pSprite->sectnum];
int x2, y2, z2; int x2, y2, z2;
short var_3C = BulletList[nBullet].field_10; short var_3C = pBullet->field_10;
int nVal; int nVal;
if (var_3C < 30000) if (var_3C < 30000)
{ {
short nEnemySprite = nBulletEnemy[nBullet]; short nEnemySprite = nBulletEnemy[nBullet];
if (nEnemySprite > -1)
if (nBulletEnemy[nBullet] <= -1) {
goto MoveBullet_goto_A; // FIXME
}
if (!(sprite[nEnemySprite].cstat & 0x101))
{ {
if (!(sprite[nEnemySprite].cstat & 0x101))
nBulletEnemy[nBullet] = -1; nBulletEnemy[nBullet] = -1;
MoveBullet_goto_A: else
{
nVal = AngleChase(nSprite, nEnemySprite, var_3C, 0, 16);
goto MOVEEND;
}
}
if (nType == 3) if (nType == 3)
{ {
if (BulletList[nBullet].field_E >= 8) if (pBullet->field_E < 8)
{ {
sprite[nSprite].xrepeat += 4; pSprite->xrepeat -= 1;
sprite[nSprite].yrepeat += 4; pSprite->yrepeat += 8;
pBullet->z -= 200;
if (pSprite->shade < 90) {
pSprite->shade += 35;
}
if (pBullet->field_E == 3)
{
pBullet->nSeq = 45;
pBullet->field_2 = 0;
pSprite->xrepeat = 40;
pSprite->yrepeat = 40;
pSprite->shade = 0;
pSprite->z += 512;
}
} }
else else
{ {
sprite[nSprite].xrepeat -= 1; pSprite->xrepeat += 4;
sprite[nSprite].yrepeat += 8; pSprite->yrepeat += 4;
BulletList[nBullet].z -= 200;
if (sprite[nSprite].shade < 90) {
sprite[nSprite].shade += 35;
}
if (BulletList[nBullet].field_E == 3)
{
BulletList[nBullet].nSeq = 45;
BulletList[nBullet].field_2 = 0;
sprite[nSprite].xrepeat = 40;
sprite[nSprite].yrepeat = 40;
sprite[nSprite].shade = 0;
sprite[nSprite].z += 512;
}
} }
} }
// loc_2A1DD // loc_2A1DD
nVal = movesprite(nSprite, BulletList[nBullet].x, BulletList[nBullet].y, BulletList[nBullet].z, sprite[nSprite].clipdist >> 1, sprite[nSprite].clipdist >> 1, CLIPMASK1); nVal = movesprite(nSprite, pBullet->x, pBullet->y, pBullet->z, pSprite->clipdist >> 1, pSprite->clipdist >> 1, CLIPMASK1);
}
else
{
nVal = AngleChase(nSprite, nEnemySprite, var_3C, 0, 16);
}
MOVEEND:
if (nVal) if (nVal)
{ {
x2 = sprite[nSprite].x; x2 = pSprite->x;
y2 = sprite[nSprite].y; y2 = pSprite->y;
z2 = sprite[nSprite].z; z2 = pSprite->z;
hitsect = sprite[nSprite].sectnum; hitsect = pSprite->sectnum;
if (nVal & 0x30000) if (nVal & 0x30000)
{ {
hitwall = nVal & 0x3FFF; hitwall = nVal & 0x3FFF;
goto loc_2A48A; goto HITWALL;
} }
else else
{ {
if ((nVal & 0xC000) == 0x8000) switch (nVal & 0xc000)
{ {
case 0x8000:
hitwall = nVal & 0x3FFF; hitwall = nVal & 0x3FFF;
goto loc_2A48A; goto HITWALL;
} case 0xc000:
else if ((nVal & 0xC000) == 0xC000)
{
hitsprite = nVal & 0x3FFF; hitsprite = nVal & 0x3FFF;
goto loc_2A405; goto HITSPRITE;
}
else {
goto loc_2A25F;
} }
} }
} }
else
{
loc_2A25F:
// sprite[nSprite].sectnum may have changed since we set nSectFlag ? // sprite[nSprite].sectnum may have changed since we set nSectFlag ?
short nFlagVal = nSectFlag ^ SectFlag[sprite[nSprite].sectnum]; short nFlagVal = nSectFlag ^ SectFlag[pSprite->sectnum];
if (nFlagVal & kSectUnderwater) if (nFlagVal & kSectUnderwater)
{ {
DestroyBullet(nBullet); DestroyBullet(nBullet);
nVal = 1; nVal = 1;
} }
if (nVal) { if (nVal == 0 && nType != 15 && nType != 3)
return nVal;
}
if (nType == 15)
{ {
return nVal; AddFlash(sprite[nSprite].sectnum, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, 0);
}
if (nType != 3)
{
AddFlash(sprite[nSprite].sectnum, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, nVal);
if (sprite[nSprite].pal != 5) { if (sprite[nSprite].pal != 5) {
sprite[nSprite].pal = 1; sprite[nSprite].pal = 1;
} }
} }
} }
}
else else
{ {
nVal = 1; nVal = 1;
@ -430,7 +384,7 @@ loc_2A25F:
{ {
vec3_t startPos = { x, y, z }; vec3_t startPos = { x, y, z };
hitdata_t hitData; hitdata_t hitData;
hitscan(&startPos, sprite[nSprite].sectnum, Sin(sprite[nSprite].ang + 512), Sin(sprite[nSprite].ang), (-Sin(BulletList[nBullet].field_C)) << 3, &hitData, CLIPMASK1); hitscan(&startPos, pSprite->sectnum, Cos(pSprite->ang), Sin(pSprite->ang), (-Sin(pBullet->field_C)) << 3, &hitData, CLIPMASK1);
x2 = hitData.pos.x; x2 = hitData.pos.x;
y2 = hitData.pos.y; y2 = hitData.pos.y;
z2 = hitData.pos.z; z2 = hitData.pos.z;
@ -446,16 +400,10 @@ loc_2A25F:
lasthitwall = hitwall; lasthitwall = hitwall;
lasthitsprite = hitsprite; lasthitsprite = hitsprite;
if (lasthitsprite > -1) if (hitsprite > -1)
{ {
loc_2A405: HITSPRITE:
if (sprite[nSprite].pal != 5 || sprite[hitsprite].statnum != 100) if (pSprite->pal == 5 && sprite[hitsprite].statnum != 100)
{
// assert(hitsect <= kMaxSectors);
BulletHitsSprite(&BulletList[nBullet], sprite[nSprite].owner, hitsprite, x2, y2, z2, hitsect);
}
else
{ {
short nPlayer = GetPlayerFromSprite(hitsprite); short nPlayer = GetPlayerFromSprite(hitsprite);
if (!PlayerList[nPlayer].bIsMummified) if (!PlayerList[nPlayer].bIsMummified)
@ -464,21 +412,27 @@ loc_2A405:
SetNewWeapon(nPlayer, kWeaponMummified); SetNewWeapon(nPlayer, kWeaponMummified);
} }
} }
else
{
// assert(hitsect <= kMaxSectors);
BulletHitsSprite(pBullet, pSprite->owner, hitsprite, x2, y2, z2, hitsect);
}
} }
else if (hitwall > -1) else if (hitwall > -1)
{ {
loc_2A48A: HITWALL:
if (wall[hitwall].picnum == kEnergy1) if (wall[hitwall].picnum == kEnergy1)
{ {
short nSector = wall[hitwall].nextsector; short nSector = wall[hitwall].nextsector;
if (nSector > -1) if (nSector > -1)
{ {
short nDamage = BulletInfo[BulletList[nBullet].nType].nDamage; short nDamage = BulletInfo[pBullet->nType].nDamage;
if (BulletList[nBullet].field_13 > 1) { if (pBullet->field_13 > 1) {
nDamage *= 2; nDamage *= 2;
} }
short nNormal = GetWallNormal(hitwall) & 0x7FF; short nNormal = GetWallNormal(hitwall) & kAngleMask;
runlist_DamageEnemy(sector[nSector].extra, nNormal, nDamage); runlist_DamageEnemy(sector[nSector].extra, nNormal, nDamage);
} }
@ -490,33 +444,21 @@ loc_2A48A:
{ {
if ((SectBelow[hitsect] >= 0 && (SectFlag[SectBelow[hitsect]] & kSectUnderwater)) || SectDepth[hitsect]) if ((SectBelow[hitsect] >= 0 && (SectFlag[SectBelow[hitsect]] & kSectUnderwater)) || SectDepth[hitsect])
{ {
sprite[nSprite].x = x2; pSprite->x = x2;
sprite[nSprite].y = y2; pSprite->y = y2;
sprite[nSprite].z = z2; pSprite->z = z2;
BuildSplash(nSprite, hitsect); BuildSplash(nSprite, hitsect);
} }
else else
{ {
BuildAnim(-1, BulletInfo[nType].field_C, 0, x2, y2, z2, hitsect, 40, BulletInfo[nType].nFlags); BuildAnim(-1, pBulletInfo->field_C, 0, x2, y2, z2, hitsect, 40, pBulletInfo->nFlags);
} }
} }
else else if (hitwall >= 0)
{ {
// short nType = BulletList[nBullet].nType; BackUpBullet(&x2, &y2, pSprite->ang);
if (hitwall < 0) if (nType != 3 || RandomSize(2) == 0)
{
sprite[nSprite].x = x2;
sprite[nSprite].y = y2;
sprite[nSprite].z = z2;
mychangespritesect(nSprite, hitsect);
}
else
{
BackUpBullet(&x2, &y2, sprite[nSprite].ang);
if (nType != 3 || !RandomSize(2))
{ {
int zOffset = RandomSize(8) << 3; int zOffset = RandomSize(8) << 3;
@ -525,21 +467,28 @@ loc_2A48A:
} }
// draws bullet puff on walls when they're shot // draws bullet puff on walls when they're shot
BuildAnim(-1, BulletInfo[nType].field_C, 0, x2, y2, z2 + zOffset, hitsect, 40, BulletInfo[nType].nFlags); BuildAnim(-1, pBulletInfo->field_C, 0, x2, y2, z2 + zOffset, hitsect, 40, pBulletInfo->nFlags);
} }
} }
else
{
pSprite->x = x2;
pSprite->y = y2;
pSprite->z = z2;
mychangespritesect(nSprite, hitsect);
}
// loc_2A639: // loc_2A639:
if (BulletInfo[nType].field_10) if (BulletInfo[nType].field_10)
{ {
nRadialBullet = nType; nRadialBullet = nType;
runlist_RadialDamageEnemy(nSprite, BulletInfo[nType].nDamage, BulletInfo[nType].field_10); runlist_RadialDamageEnemy(nSprite, pBulletInfo->nDamage, pBulletInfo->field_10);
nRadialBullet = -1; nRadialBullet = -1;
AddFlash(sprite[nSprite].sectnum, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, 128); AddFlash(pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 128);
}
} }
DestroyBullet(nBullet); DestroyBullet(nBullet);
@ -558,18 +507,20 @@ void SetBulletEnemy(short nBullet, short nEnemy)
int BuildBullet(short nSprite, int nType, int ebx, int ecx, int val1, int nAngle, int val2, int val3) int BuildBullet(short nSprite, int nType, int ebx, int ecx, int val1, int nAngle, int val2, int val3)
{ {
Bullet sBullet; Bullet sBullet;
bulletInfo *pBulletInfo = &BulletInfo[nType];
if (BulletInfo[nType].field_4 > 30000) if (pBulletInfo->field_4 > 30000)
{ {
if (val2 >= 10000) if (val2 >= 10000)
{ {
val2 -= 10000; val2 -= 10000;
short nTargetSprite = val2; short nTargetSprite = val2;
spritetype *pTargetSprite = &sprite[nTargetSprite];
// assert(sprite[nTargetSprite].sectnum <= kMaxSectors); // assert(sprite[nTargetSprite].sectnum <= kMaxSectors);
if (sprite[nTargetSprite].cstat & 0x101) if (pTargetSprite->cstat & 0x101)
{ {
sBullet.nType = nType; sBullet.nType = nType;
sBullet.field_13 = val3; sBullet.field_13 = val3;
@ -581,7 +532,7 @@ int BuildBullet(short nSprite, int nType, int ebx, int ecx, int val1, int nAngle
assert(sprite[nTargetSprite].sectnum >= 0 && sprite[nTargetSprite].sectnum < kMaxSectors); assert(sprite[nTargetSprite].sectnum >= 0 && sprite[nTargetSprite].sectnum < kMaxSectors);
BulletHitsSprite(&sBullet, nSprite, nTargetSprite, sprite[nTargetSprite].x, sprite[nTargetSprite].y, sprite[nTargetSprite].z - (nHeight >> 1), sprite[nTargetSprite].sectnum); BulletHitsSprite(&sBullet, nSprite, nTargetSprite, pTargetSprite->x, pTargetSprite->y, pTargetSprite->z - (nHeight >> 1), pTargetSprite->sectnum);
mydeletesprite(sBullet.nSprite); mydeletesprite(sBullet.nSprite);
return -1; return -1;
} }
@ -598,16 +549,16 @@ int BuildBullet(short nSprite, int nType, int ebx, int ecx, int val1, int nAngle
short nSector; short nSector;
if (sprite[nSprite].statnum != 100) if (sprite[nSprite].statnum == 100)
{
nSector = sprite[nSprite].sectnum;
}
else
{ {
nSector = nPlayerViewSect[GetPlayerFromSprite(nSprite)]; nSector = nPlayerViewSect[GetPlayerFromSprite(nSprite)];
} }
else
{
nSector = sprite[nSprite].sectnum;
}
int nBulletSprite = insertsprite(nSector, 200); short nBulletSprite = insertsprite(nSector, 200);
int nHeight = GetSpriteHeight(nSprite); int nHeight = GetSpriteHeight(nSprite);
nHeight = nHeight - (nHeight >> 2); nHeight = nHeight - (nHeight >> 2);
@ -623,13 +574,14 @@ int BuildBullet(short nSprite, int nType, int ebx, int ecx, int val1, int nAngle
assert(nBulletSprite >= 0 && nBulletSprite < kMaxSprites); assert(nBulletSprite >= 0 && nBulletSprite < kMaxSprites);
short nBullet = GrabBullet(); short nBullet = GrabBullet();
Bullet *pBullet = &BulletList[nBullet];
nBulletEnemy[nBullet] = -1; nBulletEnemy[nBullet] = -1;
sprite[nBulletSprite].cstat = 0; sprite[nBulletSprite].cstat = 0;
sprite[nBulletSprite].shade = -64; sprite[nBulletSprite].shade = -64;
if (BulletInfo[nType].nFlags & 4) { if (pBulletInfo->nFlags & 4) {
sprite[nBulletSprite].pal = 4; sprite[nBulletSprite].pal = 4;
} }
else { else {
@ -638,7 +590,7 @@ int BuildBullet(short nSprite, int nType, int ebx, int ecx, int val1, int nAngle
sprite[nBulletSprite].clipdist = 25; sprite[nBulletSprite].clipdist = 25;
short nRepeat = BulletInfo[nType].xyRepeat; short nRepeat = pBulletInfo->xyRepeat;
if (nRepeat < 0) { if (nRepeat < 0) {
nRepeat = 30; nRepeat = 30;
} }
@ -658,24 +610,24 @@ int BuildBullet(short nSprite, int nType, int ebx, int ecx, int val1, int nAngle
// GrabTimeSlot(3); // GrabTimeSlot(3);
BulletList[nBullet].field_10 = 0; pBullet->field_10 = 0;
BulletList[nBullet].field_E = BulletInfo[nType].field_2; pBullet->field_E = pBulletInfo->field_2;
BulletList[nBullet].field_2 = 0; pBullet->field_2 = 0;
short nSeq; short nSeq;
if (BulletInfo[nType].field_8 == -1) if (pBulletInfo->field_8 != -1)
{ {
BulletList[nBullet].field_12 = 1; pBullet->field_12 = 0;
nSeq = BulletInfo[nType].nSeq; nSeq = pBulletInfo->field_8;
} }
else else
{ {
BulletList[nBullet].field_12 = 0; pBullet->field_12 = 1;
nSeq = BulletInfo[nType].field_8; nSeq = pBulletInfo->nSeq;
} }
BulletList[nBullet].nSeq = nSeq; pBullet->nSeq = nSeq;
sprite[nBulletSprite].picnum = seq_GetSeqPicnum(nSeq, 0, 0); sprite[nBulletSprite].picnum = seq_GetSeqPicnum(nSeq, 0, 0);
@ -683,24 +635,20 @@ int BuildBullet(short nSprite, int nType, int ebx, int ecx, int val1, int nAngle
sprite[nBulletSprite].cstat |= 0x8000; sprite[nBulletSprite].cstat |= 0x8000;
} }
BulletList[nBullet].field_C = val2 & 0x7FF; // TODO - anglemask? pBullet->field_C = val2 & 0x7FF; // TODO - anglemask?
BulletList[nBullet].nType = nType; pBullet->nType = nType;
BulletList[nBullet].nSprite = nBulletSprite; pBullet->nSprite = nBulletSprite;
BulletList[nBullet].field_6 = runlist_AddRunRec(sprite[nBulletSprite].lotag - 1, nBullet | 0xB0000); pBullet->field_6 = runlist_AddRunRec(sprite[nBulletSprite].lotag - 1, nBullet | 0xB0000);
BulletList[nBullet].field_8 = runlist_AddRunRec(NewRun, nBullet | 0xB0000); pBullet->field_8 = runlist_AddRunRec(NewRun, nBullet | 0xB0000);
BulletList[nBullet].field_13 = val3; pBullet->field_13 = val3;
sprite[nBulletSprite].z += val1; sprite[nBulletSprite].z += val1;
int var_18; int var_18;
nSector = sprite[nBulletSprite].sectnum; nSector = sprite[nBulletSprite].sectnum;
while (1) while (sprite[nBulletSprite].z < sector[nSector].ceilingz)
{ {
if (sprite[nBulletSprite].z >= sector[nSector].ceilingz) {
break;
}
if (SectAbove[nSector] == -1) if (SectAbove[nSector] == -1)
{ {
sprite[nBulletSprite].z = sector[nSector].ceilingz; sprite[nBulletSprite].z = sector[nSector].ceilingz;
@ -713,7 +661,7 @@ int BuildBullet(short nSprite, int nType, int ebx, int ecx, int val1, int nAngle
if (val2 < 10000) if (val2 < 10000)
{ {
var_18 = ((-Sin(val2)) * BulletInfo[nType].field_4) >> 11; var_18 = ((-Sin(val2)) * pBulletInfo->field_4) >> 11;
} }
else else
{ {
@ -721,81 +669,75 @@ int BuildBullet(short nSprite, int nType, int ebx, int ecx, int val1, int nAngle
short nTargetSprite = val2; short nTargetSprite = val2;
if (BulletInfo[nType].field_4 > 30000) if ((unsigned int)pBulletInfo->field_4 > 30000)
{ {
nBulletEnemy[nBullet] = nTargetSprite; nBulletEnemy[nBullet] = nTargetSprite;
} }
else else
{ {
nHeight = GetSpriteHeight(nTargetSprite); nHeight = GetSpriteHeight(nTargetSprite);
int nHeightAdjust;
if (sprite[nTargetSprite].statnum == 100) if (sprite[nTargetSprite].statnum == 100)
{ {
nHeightAdjust = nHeight >> 2; nHeight -= nHeight >> 2;
} }
else else
{ {
nHeightAdjust = nHeight >> 1; nHeight -= nHeight >> 1;
} }
nHeight -= nHeightAdjust;
int var_20 = sprite[nTargetSprite].z - nHeight; int var_20 = sprite[nTargetSprite].z - nHeight;
int x, y; int x, y;
if (nSprite == -1 || sprite[nSprite].statnum == 100) if (nSprite != -1 && sprite[nSprite].statnum != 100)
{
x = sprite[nTargetSprite].x;
y = sprite[nTargetSprite].y;
if (sprite[nTargetSprite].statnum != 100)
{
x += (sprite[nTargetSprite].xvel * 20) >> 6;
y += (sprite[nTargetSprite].yvel * 20) >> 6;
}
else
{
int nPlayer = GetPlayerFromSprite(nTargetSprite);
if (nPlayer > -1)
{
x += nPlayerDX[nPlayer] * 15;
y += nPlayerDY[nPlayer] * 15;
}
}
x -= sprite[nBulletSprite].x;
y -= sprite[nBulletSprite].y;
nAngle = GetMyAngle(x, y);
sprite[nSprite].ang = nAngle;
}
else
{ {
// loc_2ABA3: // loc_2ABA3:
x = sprite[nTargetSprite].x - sprite[nBulletSprite].x; x = sprite[nTargetSprite].x - sprite[nBulletSprite].x;
y = sprite[nTargetSprite].y - sprite[nBulletSprite].y; y = sprite[nTargetSprite].y - sprite[nBulletSprite].y;
} }
else
{
x = sprite[nTargetSprite].x;
y = sprite[nTargetSprite].y;
if (sprite[nTargetSprite].statnum == 100)
{
int nPlayer = GetPlayerFromSprite(nTargetSprite);
if (nPlayer > -1)
{
x += ((nPlayerDX[nPlayer] << 4) - nPlayerDX[nPlayer]);
y += ((nPlayerDY[nPlayer] << 4) - nPlayerDY[nPlayer]);
}
}
else
{
short nXVel = sprite[nTargetSprite].xvel;
short nYVel = sprite[nTargetSprite].yvel;
x += (((nXVel << 2) + nXVel) << 2) >> 6;
y += (((nYVel << 2) + nYVel) << 2) >> 6;
}
y -= sprite[nBulletSprite].y;
x -= sprite[nBulletSprite].x;
nAngle = GetMyAngle(x, y);
sprite[nSprite].ang = nAngle;
}
int nSqrt = lsqrt(y*y + x*x); int nSqrt = lsqrt(y*y + x*x);
if (nSqrt <= 0) if ((unsigned int)nSqrt > 0)
{
var_18 = ((var_20 - sprite[nBulletSprite].z) * pBulletInfo->field_4) / nSqrt;
}
else
{ {
var_18 = 0; var_18 = 0;
} }
else
{
var_18 = ((var_20 - sprite[nBulletSprite].z) * BulletInfo[nType].field_4) / nSqrt;
}
} }
} }
BulletList[nBullet].z = 0; pBullet->z = 0;
BulletList[nBullet].x = (sprite[nSprite].clipdist << 2) * Sin(nAngle + 512); pBullet->x = (sprite[nSprite].clipdist << 2) * Cos(nAngle);
BulletList[nBullet].y = (sprite[nSprite].clipdist << 2) * Sin(nAngle); pBullet->y = (sprite[nSprite].clipdist << 2) * Sin(nAngle);
nBulletEnemy[nBullet] = -1; nBulletEnemy[nBullet] = -1;
if (MoveBullet(nBullet)) if (MoveBullet(nBullet))
@ -804,13 +746,13 @@ int BuildBullet(short nSprite, int nType, int ebx, int ecx, int val1, int nAngle
} }
else else
{ {
BulletList[nBullet].field_10 = BulletInfo[nType].field_4; pBullet->field_10 = pBulletInfo->field_4;
BulletList[nBullet].x = (Sin(nAngle + 512) >> 3) * BulletInfo[nType].field_4; pBullet->x = (Cos(nAngle) >> 3) * pBulletInfo->field_4;
BulletList[nBullet].y = (Sin(nAngle) >> 3) * BulletInfo[nType].field_4; pBullet->y = (Sin(nAngle) >> 3) * pBulletInfo->field_4;
BulletList[nBullet].z = var_18 >> 3; pBullet->z = var_18 >> 3;
} }
return (nBulletSprite & 0xFFFF) | (nBullet << 16); return nBulletSprite | (nBullet << 16);
} }
void FuncBullet(int a, int b, int nRun) void FuncBullet(int a, int b, int nRun)
@ -825,32 +767,6 @@ void FuncBullet(int a, int b, int nRun)
switch (nMessage) switch (nMessage)
{ {
default:
{
DebugOut("unknown msg %x for bullet\n", a & 0x7F0000);
return;
}
case 0xA0000:
return;
case 0x90000:
{
short nSprite2 = a & 0xFFFF;
tsprite[nSprite2].statnum = 1000;
if (BulletList[nBullet].nType == 15)
{
seq_PlotArrowSequence(nSprite2, nSeq, BulletList[nBullet].field_2);
}
else
{
seq_PlotSequence(nSprite2, nSeq, BulletList[nBullet].field_2, 0);
tsprite[nSprite2].owner = -1;
}
return;
}
case 0x20000: case 0x20000:
{ {
short nFlag = FrameFlag[SeqBase[nSeq] + BulletList[nBullet].field_2]; short nFlag = FrameFlag[SeqBase[nSeq] + BulletList[nBullet].field_2];
@ -874,20 +790,40 @@ void FuncBullet(int a, int b, int nRun)
BulletList[nBullet].field_2 = 0; BulletList[nBullet].field_2 = 0;
} }
if (BulletList[nBullet].field_E == -1) if (BulletList[nBullet].field_E != -1 && --BulletList[nBullet].field_E == 0)
{ {
MoveBullet(nBullet); DestroyBullet(nBullet);
} }
else else
{ {
BulletList[nBullet].field_E--;
if (!BulletList[nBullet].field_E) {
DestroyBullet(nBullet);
}
else {
MoveBullet(nBullet); MoveBullet(nBullet);
} }
break;
} }
case 0x90000:
{
short nSprite2 = a & 0xFFFF;
tsprite[nSprite2].statnum = 1000;
if (BulletList[nBullet].nType == 15)
{
seq_PlotArrowSequence(nSprite2, nSeq, BulletList[nBullet].field_2);
}
else
{
seq_PlotSequence(nSprite2, nSeq, BulletList[nBullet].field_2, 0);
tsprite[nSprite2].owner = -1;
}
break;
}
case 0xA0000:
break;
default:
{
DebugOut("unknown msg %x for bullet\n", a & 0x7F0000);
return; return;
} }
} }

View file

@ -6,6 +6,7 @@
#include "build.h" #include "build.h"
#include "pragmas.h" #include "pragmas.h"
#include "typedefs.h" #include "typedefs.h"
#include "trigdat.h"
#define kMaxTiles 6144 #define kMaxTiles 6144
#define kMaxSprites 4096 #define kMaxSprites 4096
@ -27,7 +28,12 @@ enum
inline int Sin(int angle) inline int Sin(int angle)
{ {
return sintable[angle & 0x7FF]; return sintable[angle & kAngleMask];
}
inline int Cos(int angle)
{
return sintable[(angle + 512) & kAngleMask];
} }
int movesprite(short spritenum, int dx, int dy, int dz, int ceildist, int flordist, unsigned int clipmask); int movesprite(short spritenum, int dx, int dy, int dz, int ceildist, int flordist, unsigned int clipmask);

View file

@ -296,59 +296,47 @@ int BelowNear(short nSprite)
int movespritez(short nSprite, int z, int height, int flordist, int clipdist) int movespritez(short nSprite, int z, int height, int flordist, int clipdist)
{ {
short nSector = sprite[nSprite].sectnum; spritetype* pSprite = &sprite[nSprite];
short nSector = pSprite->sectnum;
assert(nSector >= 0 && nSector < kMaxSectors); assert(nSector >= 0 && nSector < kMaxSectors);
overridesect = nSector; overridesect = nSector;
int edi = nSector; short edi = nSector;
// backup cstat // backup cstat
uint16_t cstat = sprite[nSprite].cstat; uint16_t cstat = pSprite->cstat;
sprite[nSprite].cstat &= 0xFFFE; pSprite->cstat &= ~CSTAT_SPRITE_BLOCK;
int nRet = 0; int nRet = 0;
if (SectFlag[nSector] & kSectUnderwater) { short nSectFlags = SectFlag[nSector];
if (nSectFlags & kSectUnderwater) {
z >>= 1; z >>= 1;
} }
int spriteZ = sprite[nSprite].z; int spriteZ = pSprite->z;
int floorZ = sector[nSector].floorz; int floorZ = sector[nSector].floorz;
int ebp = spriteZ + z; int ebp = spriteZ + z;
int eax = sector[nSector].ceilingz + (height >> 1); int eax = sector[nSector].ceilingz + (height >> 1);
if ((SectFlag[nSector] & kSectUnderwater) && ebp < eax) { if ((nSectFlags & kSectUnderwater) && ebp < eax) {
ebp = eax; ebp = eax;
} }
// loc_151E7: // loc_151E7:
while (1) while (ebp > sector[pSprite->sectnum].floorz && SectBelow[pSprite->sectnum] >= 0)
{ {
if (ebp <= sector[sprite[nSprite].sectnum].floorz || SectBelow[sprite[nSprite].sectnum] < 0) edi = SectBelow[pSprite->sectnum];
break;
edi = SectBelow[sprite[nSprite].sectnum];
mychangespritesect(nSprite, edi); mychangespritesect(nSprite, edi);
} }
if (edi == nSector) if (edi != nSector)
{ {
while (1) pSprite->z = ebp;
{
if ((ebp >= sector[sprite[nSprite].sectnum].ceilingz) || (SectAbove[sprite[nSprite].sectnum] < 0))
break;
edi = SectAbove[sprite[nSprite].sectnum];
mychangespritesect(nSprite, edi);
}
}
else
{
sprite[nSprite].z = ebp;
if (SectFlag[edi] & kSectUnderwater) if (SectFlag[edi] & kSectUnderwater)
{ {
@ -356,21 +344,30 @@ int movespritez(short nSprite, int z, int height, int flordist, int clipdist)
D3PlayFX(StaticSound[kSound2], nSprite); D3PlayFX(StaticSound[kSound2], nSprite);
} }
if (sprite[nSprite].statnum <= 107) { if (pSprite->statnum <= 107) {
sprite[nSprite].hitag = 0; pSprite->hitag = 0;
} }
} }
} }
else
{
while ((ebp < sector[pSprite->sectnum].ceilingz) && (SectAbove[pSprite->sectnum] >= 0))
{
edi = SectAbove[pSprite->sectnum];
mychangespritesect(nSprite, edi);
}
}
// This function will keep the player from falling off cliffs when you're too close to the edge. // This function will keep the player from falling off cliffs when you're too close to the edge.
// This function finds the highest and lowest z coordinates that your clipping BOX can get to. // This function finds the highest and lowest z coordinates that your clipping BOX can get to.
getzrange_old(sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z - 256, sprite[nSprite].sectnum, getzrange_old(pSprite->x, pSprite->y, pSprite->z - 256, pSprite->sectnum,
(int32_t*)&sprceiling, (int32_t*)&hihit, (int32_t*)&sprfloor, (int32_t*)&lohit, 128, CLIPMASK0); &sprceiling, &hihit, &sprfloor, &lohit, 128, CLIPMASK0);
int mySprfloor = sprfloor; int mySprfloor = sprfloor;
if ((lohit & 0xC000) != 0xC000) { if ((lohit & 0xC000) != 0xC000) {
mySprfloor += SectDepth[sprite[nSprite].sectnum]; mySprfloor += SectDepth[pSprite->sectnum];
} }
if (ebp > mySprfloor) if (ebp > mySprfloor)
@ -379,64 +376,24 @@ int movespritez(short nSprite, int z, int height, int flordist, int clipdist)
{ {
bTouchFloor = kTrue; bTouchFloor = kTrue;
if ((lohit & 0xC000) != 0xC000) if ((lohit & 0xC000) == 0xC000)
{
// Path B
if (SectBelow[sprite[nSprite].sectnum] == -1)
{
nRet |= 0x20000;
short nSectDamage = SectDamage[sprite[nSprite].sectnum];
if (nSectDamage != 0)
{
if (sprite[nSprite].hitag < 15)
{
IgniteSprite(nSprite);
sprite[nSprite].hitag = 20;
}
#if 0
short dx = nSectDamage;
dx >>= 2;
int eax = dx;
int edx = eax;
edx >>= 2;
eax -= edx;
int outval;
__asm
{
mov dx, nSectDamage
sar dx, 2
movsx eax, dx
mov edx, eax
sar edx, 2; // >> 4
sub eax, edx
//mov edx, eax
movsx edx, ax
mov outval, edx
}
#endif
nSectDamage >>= 2;
nSectDamage = nSectDamage - (nSectDamage>>2);
if (nSectDamage) {
runlist_DamageEnemy(nSprite, -1, nSectDamage);
}
}
sprite[nSprite].zvel = 0;
}
}
else
{ {
// Path A // Path A
short nFloorSprite = lohit & 0x3FFF; short nFloorSprite = lohit & 0x3FFF;
if (sprite[nSprite].statnum != 100 || !sprite[nFloorSprite].statnum || sprite[nFloorSprite].statnum >= 100) if (pSprite->statnum == 100 && sprite[nFloorSprite].statnum != 0 || sprite[nFloorSprite].statnum < 100)
{ {
short nStat = sprite[nFloorSprite].statnum; short nDamage = (z >> 9);
if (!nStat || nStat > 199) if (nDamage)
{
runlist_DamageEnemy(nFloorSprite, nSprite, nDamage << 1);
}
pSprite->zvel = -z;
}
else
{
if (sprite[nFloorSprite].statnum == 0 || sprite[nFloorSprite].statnum > 199)
{ {
nRet |= 0x20000; nRet |= 0x20000;
} }
@ -445,27 +402,44 @@ int movespritez(short nSprite, int z, int height, int flordist, int clipdist)
nRet |= lohit; nRet |= lohit;
} }
sprite[nSprite].zvel = 0; pSprite->zvel = 0;
}
} }
else else
{ {
if (z >> 9) // Path B
if (SectBelow[pSprite->sectnum] == -1)
{ {
runlist_DamageEnemy((lohit & 0x3FFF), nSprite, (z >> 9) * 2); nRet |= 0x20000;
short nSectDamage = SectDamage[pSprite->sectnum];
if (nSectDamage != 0)
{
if (pSprite->hitag < 15)
{
IgniteSprite(nSprite);
pSprite->hitag = 20;
}
nSectDamage >>= 2;
nSectDamage = nSectDamage - (nSectDamage>>2);
if (nSectDamage) {
runlist_DamageEnemy(nSprite, -1, nSectDamage);
}
} }
sprite[nSprite].zvel = -z; pSprite->zvel = 0;
} }
} }
} }
// loc_1543B: // loc_1543B:
ebp = mySprfloor; ebp = mySprfloor;
sprite[nSprite].z = mySprfloor; pSprite->z = mySprfloor;
} }
else else
{ {
if ((ebp - height) < sprceiling && ((hihit & 0xC000) == 0xC000 || SectAbove[sprite[nSprite].sectnum] == -1)) if ((ebp - height) < sprceiling && ((hihit & 0xC000) == 0xC000 || SectAbove[pSprite->sectnum] == -1))
{ {
ebp = sprceiling + height; ebp = sprceiling + height;
nRet |= 0x10000; nRet |= 0x10000;
@ -481,12 +455,12 @@ int movespritez(short nSprite, int z, int height, int flordist, int clipdist)
} }
} }
sprite[nSprite].cstat = cstat; // restore cstat pSprite->cstat = cstat; // restore cstat
sprite[nSprite].z = ebp; pSprite->z = ebp;
if (sprite[nSprite].statnum == 100) if (pSprite->statnum == 100)
{ {
BuildNear(sprite[nSprite].x, sprite[nSprite].y, clipdist + (clipdist / 2), sprite[nSprite].sectnum); BuildNear(pSprite->x, pSprite->y, clipdist + (clipdist / 2), pSprite->sectnum);
nRet |= BelowNear(nSprite); nRet |= BelowNear(nSprite);
} }
@ -501,17 +475,18 @@ int GetSpriteHeight(int nSprite)
// TODO - where is ceildist used? // TODO - where is ceildist used?
int movesprite(short nSprite, int dx, int dy, int dz, int ceildist, int flordist, unsigned int clipmask) int movesprite(short nSprite, int dx, int dy, int dz, int ceildist, int flordist, unsigned int clipmask)
{ {
spritetype *pSprite = &sprite[nSprite];
bTouchFloor = kFalse; bTouchFloor = kFalse;
int x = sprite[nSprite].x; int x = pSprite->x;
int y = sprite[nSprite].y; int y = pSprite->y;
int z = sprite[nSprite].z; int z = pSprite->z;
int nSpriteHeight = GetSpriteHeight(nSprite); int nSpriteHeight = GetSpriteHeight(nSprite);
int nClipDist = sprite[nSprite].clipdist << 2; int nClipDist = (int8_t)pSprite->clipdist << 2;
short nSector = sprite[nSprite].sectnum; short nSector = pSprite->sectnum;
assert(nSector >= 0 && nSector < kMaxSectors); assert(nSector >= 0 && nSector < kMaxSectors);
int floorZ = sector[nSector].floorz; int floorZ = sector[nSector].floorz;
@ -524,20 +499,18 @@ int movesprite(short nSprite, int dx, int dy, int dz, int ceildist, int flordist
dy >>= 1; dy >>= 1;
} }
short nSprite2 = nSprite;
nRet |= movespritez(nSprite, dz, nSpriteHeight, flordist, nClipDist); nRet |= movespritez(nSprite, dz, nSpriteHeight, flordist, nClipDist);
nSector = sprite[nSprite].sectnum; // modified in movespritez so re-grab this variable nSector = pSprite->sectnum; // modified in movespritez so re-grab this variable
if (sprite[nSprite].statnum == 100) if (pSprite->statnum == 100)
{ {
short nPlayer = GetPlayerFromSprite(nSprite2); short nPlayer = GetPlayerFromSprite(nSprite);
int varA = 0; int varA = 0;
int varB = 0; int varB = 0;
CheckSectorFloor(overridesect, sprite[nSprite].z, &varB, &varA); CheckSectorFloor(overridesect, pSprite->z, &varB, &varA);
if (varB || varA) if (varB || varA)
{ {
@ -550,15 +523,12 @@ int movesprite(short nSprite, int dx, int dy, int dz, int ceildist, int flordist
} }
else else
{ {
CheckSectorFloor(overridesect, sprite[nSprite].z, &dx, &dy); CheckSectorFloor(overridesect, pSprite->z, &dx, &dy);
} }
/* nRet |= (uint16_t)clipmove_old(&pSprite->x, &pSprite->y, &pSprite->z, &nSector, dx, dy, nClipDist, nSpriteHeight, flordist, clipmask);
The game masks off the top 16 bits of the return value.
*/
nRet |= clipmove_old(&sprite[nSprite].x, &sprite[nSprite].y, &sprite[nSprite].z, &nSector, dx, dy, nClipDist, nSpriteHeight, flordist, clipmask) & 0xFFFF;
if ((nSector != sprite[nSprite].sectnum) && nSector >= 0) if ((nSector != pSprite->sectnum) && nSector >= 0)
{ {
if (nRet & 0x20000) { if (nRet & 0x20000) {
dz = 0; dz = 0;
@ -566,16 +536,16 @@ int movesprite(short nSprite, int dx, int dy, int dz, int ceildist, int flordist
if ((sector[nSector].floorz - z) < (dz + flordist)) if ((sector[nSector].floorz - z) < (dz + flordist))
{ {
sprite[nSprite].x = x; pSprite->x = x;
sprite[nSprite].y = y; pSprite->y = y;
} }
else else
{ {
mychangespritesect(nSprite, nSector); mychangespritesect(nSprite, nSector);
if (sprite[nSprite].pal < 5 && !sprite[nSprite].hitag) if (pSprite->pal < 5 && !pSprite->hitag)
{ {
sprite[nSprite].pal = sector[sprite[nSprite].sectnum].ceilingpal; pSprite->pal = sector[pSprite->sectnum].ceilingpal;
} }
} }
} }
@ -1237,7 +1207,7 @@ int AngleChase(int nSprite, int nSprite2, int ebx, int ecx, int push1)
int GetWallNormal(short nWall) int GetWallNormal(short nWall)
{ {
nWall &= 0x1FFF; nWall &= kMaxWalls-1;
int nWall2 = wall[nWall].point2; int nWall2 = wall[nWall].point2;