diff --git a/source/exhumed/src/bullet.cpp b/source/exhumed/src/bullet.cpp index 7ca8418d6..bb97a3014 100644 --- a/source/exhumed/src/bullet.cpp +++ b/source/exhumed/src/bullet.cpp @@ -30,20 +30,20 @@ short BulletFree[kMaxBullets]; // 32 bytes struct Bullet { - short nSeq; // 0 - short field_2; // 2 - short nSprite; // 4 - short field_6; - short field_8; - short nType; - short field_C; - short field_E; - short field_10; - uint8_t field_12; - uint8_t field_13; - int x; - int y; - int z; + short nSeq; // 0 + short field_2; // 2 + short nSprite; // 4 + short field_6; + short field_8; + short nType; + short field_C; + short field_E; + short field_10; + uint8_t field_12; + uint8_t field_13; + int x; + int y; + int z; }; Bullet BulletList[kMaxBullets]; @@ -56,839 +56,775 @@ int nBulletCount = 0; short nRadialBullet = 0; bulletInfo BulletInfo[] = { - { 25, 1, 20, -1, -1, 13, 0, 0, -1, 0 }, - { 25, -1, 65000, -1, 31, 73, 0, 0, -1, 0 }, - { 15, -1, 60000, -1, 31, 73, 0, 0, -1, 0 }, - { 5, 15, 2000, -1, 14, 38, 4, 5, 3, 0 }, - { 250, 100, 2000, -1, 33, 34, 4, 20, -1, 0 }, - { 200, -1, 2000, -1, 20, 23, 4, 10, -1, 0 }, - { 200, -1, 60000, 68, 68, -1, -1, 0, -1, 0 }, - { 300, 1, 0, -1, -1, -1, 0, 50, -1, 0 }, - { 18, -1, 2000, -1, 18, 29, 4, 0, -1, 0 }, - { 20, -1, 2000, 37, 11, 30, 4, 0, -1, 0 }, - { 25, -1, 3000, -1, 44, 36, 4, 15, 90, 0 }, - { 30, -1, 1000, -1, 52, 53, 4, 20, 48, 0 }, - { 20, -1, 3500, -1, 54, 55, 4, 30, -1, 0 }, - { 10, -1, 5000, -1, 57, 76, 4, 0, -1, 0 }, - { 40, -1, 1500, -1, 63, 38, 4, 10, 40, 0 }, - { 20, -1, 2000, -1, 60, 12, 0, 0, -1, 0 }, - { 5, -1, 60000, -1, 31, 76, 0, 0, -1, 0 } + { 25, 1, 20, -1, -1, 13, 0, 0, -1, 0 }, + { 25, -1, 65000, -1, 31, 73, 0, 0, -1, 0 }, + { 15, -1, 60000, -1, 31, 73, 0, 0, -1, 0 }, + { 5, 15, 2000, -1, 14, 38, 4, 5, 3, 0 }, + { 250, 100, 2000, -1, 33, 34, 4, 20, -1, 0 }, + { 200, -1, 2000, -1, 20, 23, 4, 10, -1, 0 }, + { 200, -1, 60000, 68, 68, -1, -1, 0, -1, 0 }, + { 300, 1, 0, -1, -1, -1, 0, 50, -1, 0 }, + { 18, -1, 2000, -1, 18, 29, 4, 0, -1, 0 }, + { 20, -1, 2000, 37, 11, 30, 4, 0, -1, 0 }, + { 25, -1, 3000, -1, 44, 36, 4, 15, 90, 0 }, + { 30, -1, 1000, -1, 52, 53, 4, 20, 48, 0 }, + { 20, -1, 3500, -1, 54, 55, 4, 30, -1, 0 }, + { 10, -1, 5000, -1, 57, 76, 4, 0, -1, 0 }, + { 40, -1, 1500, -1, 63, 38, 4, 10, 40, 0 }, + { 20, -1, 2000, -1, 60, 12, 0, 0, -1, 0 }, + { 5, -1, 60000, -1, 31, 76, 0, 0, -1, 0 } }; void InitBullets() { - nBulletCount = 0; + nBulletCount = 0; - for (int i = 0; i < kMaxBullets; i++) { - BulletFree[i] = i; - } + for (int i = 0; i < kMaxBullets; i++) { + BulletFree[i] = i; + } - nBulletsFree = kMaxBullets; + nBulletsFree = kMaxBullets; - memset(nBulletEnemy, -1, sizeof(nBulletEnemy)); + memset(nBulletEnemy, -1, sizeof(nBulletEnemy)); } short GrabBullet() { - nBulletsFree--; - return BulletFree[nBulletsFree]; + nBulletsFree--; + return BulletFree[nBulletsFree]; } void DestroyBullet(short nBullet) { - short nSprite = BulletList[nBullet].nSprite; + short nSprite = BulletList[nBullet].nSprite; - runlist_DoSubRunRec(BulletList[nBullet].field_6); - runlist_DoSubRunRec(sprite[nSprite].lotag - 1); - runlist_SubRunRec(BulletList[nBullet].field_8); + runlist_DoSubRunRec(BulletList[nBullet].field_6); + runlist_DoSubRunRec(sprite[nSprite].lotag - 1); + runlist_SubRunRec(BulletList[nBullet].field_8); - StopSpriteSound(nSprite); + StopSpriteSound(nSprite); - mydeletesprite(nSprite); + mydeletesprite(nSprite); - BulletFree[nBulletsFree] = nBullet; - nBulletsFree++; + BulletFree[nBulletsFree] = nBullet; + nBulletsFree++; } void IgniteSprite(int nSprite) { - sprite[nSprite].hitag += 2; + sprite[nSprite].hitag += 2; - int nAnim = BuildAnim(-1, 38, 0, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, sprite[nSprite].sectnum, 40, 20);//276); - short nAnimSprite = GetAnimSprite(nAnim); + int nAnim = BuildAnim(-1, 38, 0, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, sprite[nSprite].sectnum, 40, 20);//276); + short nAnimSprite = GetAnimSprite(nAnim); - sprite[nAnimSprite].hitag = nSprite; - changespritestat(nAnimSprite, kStatIgnited); + sprite[nAnimSprite].hitag = nSprite; + changespritestat(nAnimSprite, kStatIgnited); - short yRepeat = (tilesiz[sprite[nAnimSprite].picnum].y * 32) / nFlameHeight; - if (yRepeat < 1) - yRepeat = 1; + short yRepeat = (tilesiz[sprite[nAnimSprite].picnum].y * 32) / nFlameHeight; + if (yRepeat < 1) + yRepeat = 1; - sprite[nAnimSprite].yrepeat = (uint8_t)yRepeat; + sprite[nAnimSprite].yrepeat = (uint8_t)yRepeat; } void BulletHitsSprite(Bullet *pBullet, short nBulletSprite, short nHitSprite, int x, int y, int z, int nSector) { - assert(nSector >= 0 && nSector < kMaxSectors); + assert(nSector >= 0 && nSector < kMaxSectors); - bulletInfo *pBulletInfo = &BulletInfo[pBullet->nType]; + bulletInfo *pBulletInfo = &BulletInfo[pBullet->nType]; - short nStat = sprite[nHitSprite].statnum; + short nStat = sprite[nHitSprite].statnum; - switch (pBullet->nType) - { - case 0: - case 4: - case 5: - case 6: - case 7: - case 10: - case 11: - { - break; - } + switch (pBullet->nType) + { + case 3: + { + if (nStat > 107 || nStat == 98) { + return; + } - 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; - } + sprite[nHitSprite].hitag++; - short nSprite = pBullet->nSprite; + if (sprite[nHitSprite].hitag == 15) { + IgniteSprite(nHitSprite); + } - if (nStat == 98) - { - short nAngle = sprite[nSprite].ang + 256; - int nRand = RandomSize(9); + if (!RandomSize(2)) { + BuildAnim(-1, pBulletInfo->field_C, 0, x, y, z, nSector, 40, pBulletInfo->nFlags); + } - 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; + 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; + } - sprite[nHitSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 2; - sprite[nHitSprite].yvel = Sin(sprite[nSprite].ang) >> 2; + short nSprite = pBullet->nSprite; + spritetype *pSprite = &sprite[nSprite]; + spritetype *pHitSprite = &sprite[nHitSprite]; - MoveCreature(nHitSprite); + if (nStat != 98) + { + int xVel = pHitSprite->xvel; + int yVel = pHitSprite->yvel; - sprite[nHitSprite].xvel = xVel; - sprite[nHitSprite].yvel = yVel; - } + pHitSprite->xvel = Cos(pSprite->ang) >> 2; + pHitSprite->yvel = Sin(pSprite->ang) >> 2; - break; - } + MoveCreature(nHitSprite); - case 3: - { - if (nStat > 107 || nStat == 98) { - return; - } + pHitSprite->xvel = xVel; + pHitSprite->yvel = yVel; + } + else + { + short nAngle = pSprite->ang - (RandomSize(9) - 256); - sprite[nHitSprite].hitag++; + pHitSprite->xvel = Cos(nAngle) << 1; + pHitSprite->yvel = Sin(nAngle) << 1; + pHitSprite->zvel = (-(RandomSize(3) + 1)) << 8; + } - if (sprite[nHitSprite].hitag == 15) { - IgniteSprite(nHitSprite); - } + break; + } - if (!RandomSize(2)) { - BuildAnim(-1, pBulletInfo->field_C, 0, x, y, z, nSector, 40, pBulletInfo->nFlags); - } + default: + break; + } - return; - } + // BHS_switchBreak: + short nDamage = pBulletInfo->nDamage; - default: - break; - } + if (pBullet->field_13 > 1) { + nDamage *= 2; + } - // BHS_switchBreak: - short nDamage = pBulletInfo->nDamage; + runlist_DamageEnemy(nHitSprite, nBulletSprite, nDamage); - if (pBullet->field_13 > 1) { - nDamage *= 2; - } + if (nStat <= 90 || nStat >= 199) + { + BuildAnim(-1, pBulletInfo->field_C, 0, x, y, z, nSector, 40, pBulletInfo->nFlags); + return; + } - runlist_DamageEnemy(nHitSprite, nBulletSprite, nDamage); - - if (nStat <= 90 || nStat >= 199) - { - BuildAnim(-1, pBulletInfo->field_C, 0, x, y, z, nSector, 40, pBulletInfo->nFlags); - return; - } - - if (nStat < 98) - { - if (nStat <= 0) - { - BuildAnim(-1, 12, 0, x, y, z, nSector, 40, 0); - } - else if (nStat == 97) - { - return; - } - 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; - } - 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; - } + switch (nStat) + { + case 97: + break; + case 0: + case 98: + case 102: + case 141: + case 152: + BuildAnim(-1, 12, 0, x, y, z, nSector, 40, 0); + break; + default: + 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); + } + break; + } } void BackUpBullet(int *x, int *y, short nAngle) { - *x -= Sin(nAngle + 512) >> 11; - *y -= Sin(nAngle) >> 11; + *x -= Cos(nAngle) >> 11; + *y -= Sin(nAngle) >> 11; } int MoveBullet(short nBullet) { - short hitsect = -1; - short hitwall = -1; - short hitsprite = -1; + short hitsect = -1; + short hitwall = -1; + short hitsprite = -1; - short nType = BulletList[nBullet].nType; - short nSprite = BulletList[nBullet].nSprite; + Bullet *pBullet = &BulletList[nBullet]; + short nType = pBullet->nType; + bulletInfo *pBulletInfo = &BulletInfo[nType]; - int x = sprite[nSprite].x; - int y = sprite[nSprite].y; - int z = sprite[nSprite].z; // ebx - short nSectFlag = SectFlag[sprite[nSprite].sectnum]; + short nSprite = BulletList[nBullet].nSprite; + spritetype *pSprite = &sprite[nSprite]; - int x2, y2, z2; + int x = pSprite->x; + int y = pSprite->y; + int z = pSprite->z; // ebx + short nSectFlag = SectFlag[pSprite->sectnum]; - short var_3C = BulletList[nBullet].field_10; + int x2, y2, z2; - int nVal; + short var_3C = pBullet->field_10; - if (var_3C < 30000) - { - short nEnemySprite = nBulletEnemy[nBullet]; + int nVal; - if (nBulletEnemy[nBullet] <= -1) { - goto MoveBullet_goto_A; // FIXME - } + if (var_3C < 30000) + { + short nEnemySprite = nBulletEnemy[nBullet]; + if (nEnemySprite > -1) + { + if (!(sprite[nEnemySprite].cstat & 0x101)) + nBulletEnemy[nBullet] = -1; + else + { + nVal = AngleChase(nSprite, nEnemySprite, var_3C, 0, 16); + goto MOVEEND; + } + } + if (nType == 3) + { + if (pBullet->field_E < 8) + { + pSprite->xrepeat -= 1; + pSprite->yrepeat += 8; - if (!(sprite[nEnemySprite].cstat & 0x101)) - { - nBulletEnemy[nBullet] = -1; -MoveBullet_goto_A: - if (nType == 3) - { - if (BulletList[nBullet].field_E >= 8) - { - sprite[nSprite].xrepeat += 4; - sprite[nSprite].yrepeat += 4; - } - else - { - sprite[nSprite].xrepeat -= 1; - sprite[nSprite].yrepeat += 8; + pBullet->z -= 200; - BulletList[nBullet].z -= 200; + if (pSprite->shade < 90) { + pSprite->shade += 35; + } - if (sprite[nSprite].shade < 90) { - sprite[nSprite].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 + { + pSprite->xrepeat += 4; + pSprite->yrepeat += 4; + } + } - 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 + nVal = movesprite(nSprite, pBullet->x, pBullet->y, pBullet->z, pSprite->clipdist >> 1, pSprite->clipdist >> 1, CLIPMASK1); - // loc_2A1DD - nVal = movesprite(nSprite, BulletList[nBullet].x, BulletList[nBullet].y, BulletList[nBullet].z, sprite[nSprite].clipdist >> 1, sprite[nSprite].clipdist >> 1, CLIPMASK1); - } - else - { - nVal = AngleChase(nSprite, nEnemySprite, var_3C, 0, 16); - } +MOVEEND: + if (nVal) + { + x2 = pSprite->x; + y2 = pSprite->y; + z2 = pSprite->z; + hitsect = pSprite->sectnum; - if (nVal) - { - x2 = sprite[nSprite].x; - y2 = sprite[nSprite].y; - z2 = sprite[nSprite].z; - hitsect = sprite[nSprite].sectnum; + if (nVal & 0x30000) + { + hitwall = nVal & 0x3FFF; + goto HITWALL; + } + else + { + switch (nVal & 0xc000) + { + case 0x8000: + hitwall = nVal & 0x3FFF; + goto HITWALL; + case 0xc000: + hitsprite = nVal & 0x3FFF; + goto HITSPRITE; + } + } + } - if (nVal & 0x30000) - { - hitwall = nVal & 0x3FFF; - goto loc_2A48A; - } - else - { - if ((nVal & 0xC000) == 0x8000) - { - hitwall = nVal & 0x3FFF; - goto loc_2A48A; - } - else if ((nVal & 0xC000) == 0xC000) - { - hitsprite = nVal & 0x3FFF; - goto loc_2A405; - } - else { - goto loc_2A25F; - } - } - } - else - { -loc_2A25F: - // sprite[nSprite].sectnum may have changed since we set nSectFlag ? - short nFlagVal = nSectFlag ^ SectFlag[sprite[nSprite].sectnum]; - if (nFlagVal & kSectUnderwater) - { - DestroyBullet(nBullet); - nVal = 1; - } + // sprite[nSprite].sectnum may have changed since we set nSectFlag ? + short nFlagVal = nSectFlag ^ SectFlag[pSprite->sectnum]; + if (nFlagVal & kSectUnderwater) + { + DestroyBullet(nBullet); + nVal = 1; + } - if (nVal) { - return nVal; - } + if (nVal == 0 && nType != 15 && nType != 3) + { + AddFlash(sprite[nSprite].sectnum, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, 0); - if (nType == 15) - { - return nVal; - } + if (sprite[nSprite].pal != 5) { + sprite[nSprite].pal = 1; + } + } + } + else + { + nVal = 1; - if (nType != 3) - { - AddFlash(sprite[nSprite].sectnum, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, nVal); - - if (sprite[nSprite].pal != 5) { - sprite[nSprite].pal = 1; - } - } - } - } - else - { - nVal = 1; - - if (nBulletEnemy[nBullet] > -1) - { - hitsprite = nBulletEnemy[nBullet]; - x2 = sprite[hitsprite].x; - y2 = sprite[hitsprite].y; - z2 = sprite[hitsprite].z - (GetSpriteHeight(hitsprite) >> 1); - hitsect = sprite[hitsprite].sectnum; - } - else - { + if (nBulletEnemy[nBullet] > -1) + { + hitsprite = nBulletEnemy[nBullet]; + x2 = sprite[hitsprite].x; + y2 = sprite[hitsprite].y; + z2 = sprite[hitsprite].z - (GetSpriteHeight(hitsprite) >> 1); + hitsect = sprite[hitsprite].sectnum; + } + else + { vec3_t startPos = { x, y, z }; 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; y2 = hitData.pos.y; z2 = hitData.pos.z; hitsprite = hitData.sprite; hitsect = hitData.sect; hitwall = hitData.wall; - } + } - lasthitx = x2; - lasthity = y2; - lasthitz = z2; - lasthitsect = hitsect; - lasthitwall = hitwall; - lasthitsprite = hitsprite; + lasthitx = x2; + lasthity = y2; + lasthitz = z2; + lasthitsect = hitsect; + lasthitwall = hitwall; + lasthitsprite = hitsprite; - if (lasthitsprite > -1) - { -loc_2A405: - if (sprite[nSprite].pal != 5 || sprite[hitsprite].statnum != 100) - { + if (hitsprite > -1) + { +HITSPRITE: + if (pSprite->pal == 5 && sprite[hitsprite].statnum != 100) + { + short nPlayer = GetPlayerFromSprite(hitsprite); + if (!PlayerList[nPlayer].bIsMummified) + { + PlayerList[nPlayer].bIsMummified = kTrue; + SetNewWeapon(nPlayer, kWeaponMummified); + } + } + else + { // assert(hitsect <= kMaxSectors); - BulletHitsSprite(&BulletList[nBullet], sprite[nSprite].owner, hitsprite, x2, y2, z2, hitsect); - } - else - { - short nPlayer = GetPlayerFromSprite(hitsprite); - if (!PlayerList[nPlayer].bIsMummified) - { - PlayerList[nPlayer].bIsMummified = kTrue; - SetNewWeapon(nPlayer, kWeaponMummified); - } - } - } - else if (hitwall > -1) - { -loc_2A48A: - if (wall[hitwall].picnum == kEnergy1) - { - short nSector = wall[hitwall].nextsector; - if (nSector > -1) - { - short nDamage = BulletInfo[BulletList[nBullet].nType].nDamage; - if (BulletList[nBullet].field_13 > 1) { - nDamage *= 2; - } + BulletHitsSprite(pBullet, pSprite->owner, hitsprite, x2, y2, z2, hitsect); + } + } + else if (hitwall > -1) + { +HITWALL: + if (wall[hitwall].picnum == kEnergy1) + { + short nSector = wall[hitwall].nextsector; + if (nSector > -1) + { + short nDamage = BulletInfo[pBullet->nType].nDamage; + if (pBullet->field_13 > 1) { + 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); + } + } + } - // loc_2A4F5:? - if (hitsprite < 0 && hitwall < 0) - { - if ((SectBelow[hitsect] >= 0 && (SectFlag[SectBelow[hitsect]] & kSectUnderwater)) || SectDepth[hitsect]) - { - sprite[nSprite].x = x2; - sprite[nSprite].y = y2; - sprite[nSprite].z = z2; - BuildSplash(nSprite, hitsect); - } - else - { - BuildAnim(-1, BulletInfo[nType].field_C, 0, x2, y2, z2, hitsect, 40, BulletInfo[nType].nFlags); - } - } - else - { -// short nType = BulletList[nBullet].nType; - - if (hitwall < 0) - { - sprite[nSprite].x = x2; - sprite[nSprite].y = y2; - sprite[nSprite].z = z2; + // loc_2A4F5:? + if (hitsprite < 0 && hitwall < 0) + { + if ((SectBelow[hitsect] >= 0 && (SectFlag[SectBelow[hitsect]] & kSectUnderwater)) || SectDepth[hitsect]) + { + pSprite->x = x2; + pSprite->y = y2; + pSprite->z = z2; + BuildSplash(nSprite, hitsect); + } + else + { + BuildAnim(-1, pBulletInfo->field_C, 0, x2, y2, z2, hitsect, 40, pBulletInfo->nFlags); + } + } + else if (hitwall >= 0) + { + BackUpBullet(&x2, &y2, pSprite->ang); - mychangespritesect(nSprite, hitsect); - } - else - { - BackUpBullet(&x2, &y2, sprite[nSprite].ang); + if (nType != 3 || RandomSize(2) == 0) + { + int zOffset = RandomSize(8) << 3; - if (nType != 3 || !RandomSize(2)) - { - int zOffset = RandomSize(8) << 3; + if (!RandomBit()) { + zOffset = -zOffset; + } - if (!RandomBit()) { - zOffset = -zOffset; - } + // draws bullet puff on walls when they're shot + BuildAnim(-1, pBulletInfo->field_C, 0, x2, y2, z2 + zOffset, hitsect, 40, pBulletInfo->nFlags); + } + } + else + { + pSprite->x = x2; + pSprite->y = y2; + pSprite->z = z2; - // 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); - } - } + mychangespritesect(nSprite, hitsect); + } - // loc_2A639: - if (BulletInfo[nType].field_10) - { - nRadialBullet = nType; + // loc_2A639: + if (BulletInfo[nType].field_10) + { + 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); + } - return nVal; + return nVal; } void SetBulletEnemy(short nBullet, short nEnemy) { - if (nBullet >= 0) { - nBulletEnemy[nBullet] = nEnemy; - } + if (nBullet >= 0) { + nBulletEnemy[nBullet] = nEnemy; + } } 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 (val2 >= 10000) - { - val2 -= 10000; + if (pBulletInfo->field_4 > 30000) + { + if (val2 >= 10000) + { + val2 -= 10000; - short nTargetSprite = val2; + short nTargetSprite = val2; + spritetype *pTargetSprite = &sprite[nTargetSprite]; // assert(sprite[nTargetSprite].sectnum <= kMaxSectors); - if (sprite[nTargetSprite].cstat & 0x101) - { - sBullet.nType = nType; - sBullet.field_13 = val3; + if (pTargetSprite->cstat & 0x101) + { + sBullet.nType = nType; + sBullet.field_13 = val3; - sBullet.nSprite = insertsprite(sprite[nSprite].sectnum, 200); - sprite[sBullet.nSprite].ang = nAngle; + sBullet.nSprite = insertsprite(sprite[nSprite].sectnum, 200); + sprite[sBullet.nSprite].ang = nAngle; - int nHeight = GetSpriteHeight(nTargetSprite); + int nHeight = GetSpriteHeight(nTargetSprite); - 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); - mydeletesprite(sBullet.nSprite); - return -1; - } - else - { - val2 = 0; - } - } - } + BulletHitsSprite(&sBullet, nSprite, nTargetSprite, pTargetSprite->x, pTargetSprite->y, pTargetSprite->z - (nHeight >> 1), pTargetSprite->sectnum); + mydeletesprite(sBullet.nSprite); + return -1; + } + else + { + val2 = 0; + } + } + } - if (!nBulletsFree) { - return -1; - } + if (!nBulletsFree) { + return -1; + } - short nSector; + short nSector; - if (sprite[nSprite].statnum != 100) - { - nSector = sprite[nSprite].sectnum; - } - else - { - nSector = nPlayerViewSect[GetPlayerFromSprite(nSprite)]; - } + if (sprite[nSprite].statnum == 100) + { + nSector = nPlayerViewSect[GetPlayerFromSprite(nSprite)]; + } + else + { + nSector = sprite[nSprite].sectnum; + } - int nBulletSprite = insertsprite(nSector, 200); - int nHeight = GetSpriteHeight(nSprite); - nHeight = nHeight - (nHeight >> 2); + short nBulletSprite = insertsprite(nSector, 200); + int nHeight = GetSpriteHeight(nSprite); + nHeight = nHeight - (nHeight >> 2); - if (val1 == -1) { - val1 = -nHeight; - } + if (val1 == -1) { + val1 = -nHeight; + } - sprite[nBulletSprite].x = sprite[nSprite].x; - sprite[nBulletSprite].y = sprite[nSprite].y; - sprite[nBulletSprite].z = sprite[nSprite].z; + sprite[nBulletSprite].x = sprite[nSprite].x; + sprite[nBulletSprite].y = sprite[nSprite].y; + sprite[nBulletSprite].z = sprite[nSprite].z; - // why is this done here??? - assert(nBulletSprite >= 0 && nBulletSprite < kMaxSprites); + // why is this done here??? + 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].shade = -64; + sprite[nBulletSprite].cstat = 0; + sprite[nBulletSprite].shade = -64; - if (BulletInfo[nType].nFlags & 4) { - sprite[nBulletSprite].pal = 4; - } - else { - sprite[nBulletSprite].pal = 0; - } + if (pBulletInfo->nFlags & 4) { + sprite[nBulletSprite].pal = 4; + } + else { + sprite[nBulletSprite].pal = 0; + } - sprite[nBulletSprite].clipdist = 25; + sprite[nBulletSprite].clipdist = 25; - short nRepeat = BulletInfo[nType].xyRepeat; - if (nRepeat < 0) { - nRepeat = 30; - } + short nRepeat = pBulletInfo->xyRepeat; + if (nRepeat < 0) { + nRepeat = 30; + } - sprite[nBulletSprite].xrepeat = nRepeat; - sprite[nBulletSprite].yrepeat = nRepeat; - sprite[nBulletSprite].xoffset = 0; - sprite[nBulletSprite].yoffset = 0; - sprite[nBulletSprite].ang = nAngle; - sprite[nBulletSprite].xvel = 0; - sprite[nBulletSprite].yvel = 0; - sprite[nBulletSprite].zvel = 0; - sprite[nBulletSprite].owner = nSprite; - sprite[nBulletSprite].lotag = runlist_HeadRun() + 1; - sprite[nBulletSprite].extra = -1; - sprite[nBulletSprite].hitag = 0; + sprite[nBulletSprite].xrepeat = nRepeat; + sprite[nBulletSprite].yrepeat = nRepeat; + sprite[nBulletSprite].xoffset = 0; + sprite[nBulletSprite].yoffset = 0; + sprite[nBulletSprite].ang = nAngle; + sprite[nBulletSprite].xvel = 0; + sprite[nBulletSprite].yvel = 0; + sprite[nBulletSprite].zvel = 0; + sprite[nBulletSprite].owner = nSprite; + sprite[nBulletSprite].lotag = runlist_HeadRun() + 1; + sprite[nBulletSprite].extra = -1; + sprite[nBulletSprite].hitag = 0; // GrabTimeSlot(3); - BulletList[nBullet].field_10 = 0; - BulletList[nBullet].field_E = BulletInfo[nType].field_2; - BulletList[nBullet].field_2 = 0; + pBullet->field_10 = 0; + pBullet->field_E = pBulletInfo->field_2; + pBullet->field_2 = 0; - short nSeq; + short nSeq; - if (BulletInfo[nType].field_8 == -1) - { - BulletList[nBullet].field_12 = 1; - nSeq = BulletInfo[nType].nSeq; - } - else - { - BulletList[nBullet].field_12 = 0; - nSeq = BulletInfo[nType].field_8; - } + if (pBulletInfo->field_8 != -1) + { + pBullet->field_12 = 0; + nSeq = pBulletInfo->field_8; + } + else + { + pBullet->field_12 = 1; + 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); - if (nSeq == kSeqBullet) { - sprite[nBulletSprite].cstat |= 0x8000; - } + if (nSeq == kSeqBullet) { + sprite[nBulletSprite].cstat |= 0x8000; + } - BulletList[nBullet].field_C = val2 & 0x7FF; // TODO - anglemask? - BulletList[nBullet].nType = nType; - BulletList[nBullet].nSprite = nBulletSprite; - BulletList[nBullet].field_6 = runlist_AddRunRec(sprite[nBulletSprite].lotag - 1, nBullet | 0xB0000); - BulletList[nBullet].field_8 = runlist_AddRunRec(NewRun, nBullet | 0xB0000); - BulletList[nBullet].field_13 = val3; - sprite[nBulletSprite].z += val1; + pBullet->field_C = val2 & 0x7FF; // TODO - anglemask? + pBullet->nType = nType; + pBullet->nSprite = nBulletSprite; + pBullet->field_6 = runlist_AddRunRec(sprite[nBulletSprite].lotag - 1, nBullet | 0xB0000); + pBullet->field_8 = runlist_AddRunRec(NewRun, nBullet | 0xB0000); + pBullet->field_13 = val3; + sprite[nBulletSprite].z += val1; - int var_18; + int var_18; - nSector = sprite[nBulletSprite].sectnum; + nSector = sprite[nBulletSprite].sectnum; - while (1) - { - if (sprite[nBulletSprite].z >= sector[nSector].ceilingz) { - break; - } + while (sprite[nBulletSprite].z < sector[nSector].ceilingz) + { + if (SectAbove[nSector] == -1) + { + sprite[nBulletSprite].z = sector[nSector].ceilingz; + break; + } - if (SectAbove[nSector] == -1) - { - sprite[nBulletSprite].z = sector[nSector].ceilingz; - break; - } + nSector = SectAbove[nSector]; + mychangespritesect(nBulletSprite, nSector); + } - nSector = SectAbove[nSector]; - mychangespritesect(nBulletSprite, nSector); - } + if (val2 < 10000) + { + var_18 = ((-Sin(val2)) * pBulletInfo->field_4) >> 11; + } + else + { + val2 -= 10000; - if (val2 < 10000) - { - var_18 = ((-Sin(val2)) * BulletInfo[nType].field_4) >> 11; - } - else - { - val2 -= 10000; + short nTargetSprite = val2; - short nTargetSprite = val2; + if ((unsigned int)pBulletInfo->field_4 > 30000) + { + nBulletEnemy[nBullet] = nTargetSprite; + } + else + { + nHeight = GetSpriteHeight(nTargetSprite); - if (BulletInfo[nType].field_4 > 30000) - { - nBulletEnemy[nBullet] = nTargetSprite; - } - else - { - nHeight = GetSpriteHeight(nTargetSprite); - int nHeightAdjust; + if (sprite[nTargetSprite].statnum == 100) + { + nHeight -= nHeight >> 2; + } + else + { + nHeight -= nHeight >> 1; + } - if (sprite[nTargetSprite].statnum == 100) - { - nHeightAdjust = nHeight >> 2; - } - else - { - nHeightAdjust = nHeight >> 1; - } + int var_20 = sprite[nTargetSprite].z - nHeight; - nHeight -= nHeightAdjust; + int x, y; - int var_20 = sprite[nTargetSprite].z - nHeight; + if (nSprite != -1 && sprite[nSprite].statnum != 100) + { + x = sprite[nTargetSprite].x; + y = sprite[nTargetSprite].y; - int x, 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; + } + } - if (nSprite == -1 || sprite[nSprite].statnum == 100) - { - // loc_2ABA3: - x = sprite[nTargetSprite].x - sprite[nBulletSprite].x; - y = sprite[nTargetSprite].y - sprite[nBulletSprite].y; - } - else - { - x = sprite[nTargetSprite].x; - y = sprite[nTargetSprite].y; + x -= sprite[nBulletSprite].x; + y -= sprite[nBulletSprite].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; + nAngle = GetMyAngle(x, y); + sprite[nSprite].ang = nAngle; + } + else + { + // loc_2ABA3: + x = sprite[nTargetSprite].x - sprite[nBulletSprite].x; + y = sprite[nTargetSprite].y - sprite[nBulletSprite].y; + } - x += (((nXVel << 2) + nXVel) << 2) >> 6; - y += (((nYVel << 2) + nYVel) << 2) >> 6; - } + int nSqrt = lsqrt(y*y + x*x); + if ((unsigned int)nSqrt > 0) + { + var_18 = ((var_20 - sprite[nBulletSprite].z) * pBulletInfo->field_4) / nSqrt; + } + else + { + var_18 = 0; + } + } + } - y -= sprite[nBulletSprite].y; - x -= sprite[nBulletSprite].x; + pBullet->z = 0; + pBullet->x = (sprite[nSprite].clipdist << 2) * Cos(nAngle); + pBullet->y = (sprite[nSprite].clipdist << 2) * Sin(nAngle); + nBulletEnemy[nBullet] = -1; - nAngle = GetMyAngle(x, y); - sprite[nSprite].ang = nAngle; - } + if (MoveBullet(nBullet)) + { + nBulletSprite = -1; + } + else + { + pBullet->field_10 = pBulletInfo->field_4; + pBullet->x = (Cos(nAngle) >> 3) * pBulletInfo->field_4; + pBullet->y = (Sin(nAngle) >> 3) * pBulletInfo->field_4; + pBullet->z = var_18 >> 3; + } - int nSqrt = lsqrt(y*y + x*x); - if (nSqrt <= 0) - { - var_18 = 0; - } - else - { - var_18 = ((var_20 - sprite[nBulletSprite].z) * BulletInfo[nType].field_4) / nSqrt; - } - } - } - - BulletList[nBullet].z = 0; - BulletList[nBullet].x = (sprite[nSprite].clipdist << 2) * Sin(nAngle + 512); - BulletList[nBullet].y = (sprite[nSprite].clipdist << 2) * Sin(nAngle); - nBulletEnemy[nBullet] = -1; - - if (MoveBullet(nBullet)) - { - nBulletSprite = -1; - } - else - { - BulletList[nBullet].field_10 = BulletInfo[nType].field_4; - BulletList[nBullet].x = (Sin(nAngle + 512) >> 3) * BulletInfo[nType].field_4; - BulletList[nBullet].y = (Sin(nAngle) >> 3) * BulletInfo[nType].field_4; - BulletList[nBullet].z = var_18 >> 3; - } - - return (nBulletSprite & 0xFFFF) | (nBullet << 16); + return nBulletSprite | (nBullet << 16); } void FuncBullet(int a, int b, int nRun) { - short nBullet = RunData[nRun].nVal; - assert(nBullet >= 0 && nBullet < kMaxBullets); + short nBullet = RunData[nRun].nVal; + assert(nBullet >= 0 && nBullet < kMaxBullets); - short nSeq = SeqOffsets[BulletList[nBullet].nSeq]; - short nSprite = BulletList[nBullet].nSprite; + short nSeq = SeqOffsets[BulletList[nBullet].nSeq]; + short nSprite = BulletList[nBullet].nSprite; - int nMessage = a & 0x7F0000; + int nMessage = a & 0x7F0000; - switch (nMessage) - { - default: - { - DebugOut("unknown msg %x for bullet\n", a & 0x7F0000); - return; - } + switch (nMessage) + { + case 0x20000: + { + short nFlag = FrameFlag[SeqBase[nSeq] + BulletList[nBullet].field_2]; - case 0xA0000: - return; + seq_MoveSequence(nSprite, nSeq, BulletList[nBullet].field_2); - case 0x90000: - { - short nSprite2 = a & 0xFFFF; - tsprite[nSprite2].statnum = 1000; + if (nFlag & 0x80) + { + BuildAnim(-1, 45, 0, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, sprite[nSprite].sectnum, sprite[nSprite].xrepeat, 0); + } - 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; - } + BulletList[nBullet].field_2++; + if (BulletList[nBullet].field_2 >= SeqSize[nSeq]) + { + if (!BulletList[nBullet].field_12) + { + BulletList[nBullet].nSeq = BulletInfo[BulletList[nBullet].nType].nSeq; + BulletList[nBullet].field_12++; + } - case 0x20000: - { - short nFlag = FrameFlag[SeqBase[nSeq] + BulletList[nBullet].field_2]; + BulletList[nBullet].field_2 = 0; + } - seq_MoveSequence(nSprite, nSeq, BulletList[nBullet].field_2); + if (BulletList[nBullet].field_E != -1 && --BulletList[nBullet].field_E == 0) + { + DestroyBullet(nBullet); + } + else + { + MoveBullet(nBullet); + } + break; + } - if (nFlag & 0x80) - { - BuildAnim(-1, 45, 0, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, sprite[nSprite].sectnum, sprite[nSprite].xrepeat, 0); - } + case 0x90000: + { + short nSprite2 = a & 0xFFFF; + tsprite[nSprite2].statnum = 1000; - BulletList[nBullet].field_2++; - if (BulletList[nBullet].field_2 >= SeqSize[nSeq]) - { - if (!BulletList[nBullet].field_12) - { - BulletList[nBullet].nSeq = BulletInfo[BulletList[nBullet].nType].nSeq; - BulletList[nBullet].field_12++; - } + 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; + } - BulletList[nBullet].field_2 = 0; - } + case 0xA0000: + break; - if (BulletList[nBullet].field_E == -1) - { - MoveBullet(nBullet); - } - else - { - BulletList[nBullet].field_E--; - if (!BulletList[nBullet].field_E) { - DestroyBullet(nBullet); - } - else { - MoveBullet(nBullet); - } - } - return; - } - } + default: + { + DebugOut("unknown msg %x for bullet\n", a & 0x7F0000); + return; + } + } } diff --git a/source/exhumed/src/engine.h b/source/exhumed/src/engine.h index 81dc7d71e..79add7aca 100644 --- a/source/exhumed/src/engine.h +++ b/source/exhumed/src/engine.h @@ -6,6 +6,7 @@ #include "build.h" #include "pragmas.h" #include "typedefs.h" +#include "trigdat.h" #define kMaxTiles 6144 #define kMaxSprites 4096 @@ -27,7 +28,12 @@ enum 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); diff --git a/source/exhumed/src/move.cpp b/source/exhumed/src/move.cpp index 6f6a03f0b..de45101b1 100644 --- a/source/exhumed/src/move.cpp +++ b/source/exhumed/src/move.cpp @@ -296,59 +296,47 @@ int BelowNear(short nSprite) 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); overridesect = nSector; - int edi = nSector; + short edi = nSector; // 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; - if (SectFlag[nSector] & kSectUnderwater) { + short nSectFlags = SectFlag[nSector]; + + if (nSectFlags & kSectUnderwater) { z >>= 1; } - int spriteZ = sprite[nSprite].z; + int spriteZ = pSprite->z; int floorZ = sector[nSector].floorz; int ebp = spriteZ + z; int eax = sector[nSector].ceilingz + (height >> 1); - if ((SectFlag[nSector] & kSectUnderwater) && ebp < eax) { + if ((nSectFlags & kSectUnderwater) && ebp < eax) { ebp = eax; } // 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) - break; - - edi = SectBelow[sprite[nSprite].sectnum]; + edi = SectBelow[pSprite->sectnum]; mychangespritesect(nSprite, edi); } - if (edi == nSector) + if (edi != nSector) { - while (1) - { - 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; + pSprite->z = ebp; if (SectFlag[edi] & kSectUnderwater) { @@ -356,21 +344,30 @@ int movespritez(short nSprite, int z, int height, int flordist, int clipdist) D3PlayFX(StaticSound[kSound2], nSprite); } - if (sprite[nSprite].statnum <= 107) { - sprite[nSprite].hitag = 0; + if (pSprite->statnum <= 107) { + 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 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, - (int32_t*)&sprceiling, (int32_t*)&hihit, (int32_t*)&sprfloor, (int32_t*)&lohit, 128, CLIPMASK0); + getzrange_old(pSprite->x, pSprite->y, pSprite->z - 256, pSprite->sectnum, + &sprceiling, &hihit, &sprfloor, &lohit, 128, CLIPMASK0); int mySprfloor = sprfloor; if ((lohit & 0xC000) != 0xC000) { - mySprfloor += SectDepth[sprite[nSprite].sectnum]; + mySprfloor += SectDepth[pSprite->sectnum]; } if (ebp > mySprfloor) @@ -379,64 +376,24 @@ int movespritez(short nSprite, int z, int height, int flordist, int clipdist) { bTouchFloor = kTrue; - 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 + if ((lohit & 0xC000) == 0xC000) { // Path A 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; - if (!nStat || nStat > 199) + short nDamage = (z >> 9); + if (nDamage) + { + runlist_DamageEnemy(nFloorSprite, nSprite, nDamage << 1); + } + + pSprite->zvel = -z; + } + else + { + if (sprite[nFloorSprite].statnum == 0 || sprite[nFloorSprite].statnum > 199) { nRet |= 0x20000; } @@ -445,27 +402,44 @@ int movespritez(short nSprite, int z, int height, int flordist, int clipdist) nRet |= lohit; } - sprite[nSprite].zvel = 0; + pSprite->zvel = 0; } - else + } + else + { + // Path B + if (SectBelow[pSprite->sectnum] == -1) { - if (z >> 9) + nRet |= 0x20000; + + short nSectDamage = SectDamage[pSprite->sectnum]; + + if (nSectDamage != 0) { - runlist_DamageEnemy((lohit & 0x3FFF), nSprite, (z >> 9) * 2); + 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: ebp = mySprfloor; - sprite[nSprite].z = mySprfloor; + pSprite->z = mySprfloor; } 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; nRet |= 0x10000; @@ -481,12 +455,12 @@ int movespritez(short nSprite, int z, int height, int flordist, int clipdist) } } - sprite[nSprite].cstat = cstat; // restore cstat - sprite[nSprite].z = ebp; + pSprite->cstat = cstat; // restore cstat + 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); } @@ -501,17 +475,18 @@ int GetSpriteHeight(int nSprite) // TODO - where is ceildist used? int movesprite(short nSprite, int dx, int dy, int dz, int ceildist, int flordist, unsigned int clipmask) { + spritetype *pSprite = &sprite[nSprite]; bTouchFloor = kFalse; - int x = sprite[nSprite].x; - int y = sprite[nSprite].y; - int z = sprite[nSprite].z; + int x = pSprite->x; + int y = pSprite->y; + int z = pSprite->z; 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); 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; } - short nSprite2 = nSprite; - 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 varB = 0; - CheckSectorFloor(overridesect, sprite[nSprite].z, &varB, &varA); + CheckSectorFloor(overridesect, pSprite->z, &varB, &varA); if (varB || varA) { @@ -550,15 +523,12 @@ int movesprite(short nSprite, int dx, int dy, int dz, int ceildist, int flordist } else { - CheckSectorFloor(overridesect, sprite[nSprite].z, &dx, &dy); + CheckSectorFloor(overridesect, pSprite->z, &dx, &dy); } - /* - 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; + nRet |= (uint16_t)clipmove_old(&pSprite->x, &pSprite->y, &pSprite->z, &nSector, dx, dy, nClipDist, nSpriteHeight, flordist, clipmask); - if ((nSector != sprite[nSprite].sectnum) && nSector >= 0) + if ((nSector != pSprite->sectnum) && nSector >= 0) { if (nRet & 0x20000) { 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)) { - sprite[nSprite].x = x; - sprite[nSprite].y = y; + pSprite->x = x; + pSprite->y = y; } else { 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) { - nWall &= 0x1FFF; + nWall &= kMaxWalls-1; int nWall2 = wall[nWall].point2;