diff --git a/source/games/duke/src/zz_player.cpp b/source/games/duke/src/zz_player.cpp index ad7f1fdc6..167eb5a62 100644 --- a/source/games/duke/src/zz_player.cpp +++ b/source/games/duke/src/zz_player.cpp @@ -130,1222 +130,6 @@ static void P_IncurDamage(DukePlayer_t * const pPlayer) sprite[pPlayer->i].extra = pPlayer->last_extra + playerDamage; } -static void Proj_DoWaterTracers(vec3_t startPos, vec3_t const *endPos, int n, int16_t sectNum) -{ - if ((klabs(startPos.x - endPos->x) + klabs(startPos.y - endPos->y)) < 3084) - return; - - vec3_t const v_inc = { tabledivide32_noinline(endPos->x - startPos.x, n + 1), tabledivide32_noinline(endPos->y - startPos.y, n + 1), - tabledivide32_noinline(endPos->z - startPos.z, n + 1) }; - - for (bssize_t i=n; i>0; i--) - { - startPos.x += v_inc.x; - startPos.y += v_inc.y; - startPos.z += v_inc.z; - - updatesector(startPos.x, startPos.y, §Num); - - if (sectNum < 0) - break; - int32_t const r1 = krand2(), r2 = krand2(), r3 = krand2(); - A_InsertSprite(sectNum, startPos.x, startPos.y, startPos.z, TILE_WATERBUBBLE, -32, 4 + (r3 & 3), 4 + (r2 & 3), r1 & 2047, 0, 0, - g_player[0].ps->i, 5); - } -} - -static int A_FindTargetSprite(const spritetype *pSprite, int projAng, int projecTile) -{ - static int const aimstats[] = { - STAT_PLAYER, STAT_DUMMYPLAYER, STAT_ACTOR, STAT_ZOMBIEACTOR - }; - - int const playerNum = pSprite->picnum == TILE_APLAYER ? P_GetP(pSprite) : -1; - - if (playerNum != -1) - { - if (!g_player[playerNum].ps->auto_aim && (!RRRA || projecTile != TILE_RPG2)) - return -1; - - if (g_player[playerNum].ps->auto_aim == 2) - { - switch (DYNAMICTILEMAP(projecTile)) - { - case TONGUE__STATIC: - case FREEZEBLAST__STATIC: - case SHRINKSPARK__STATIC: - case SHRINKER__STATIC: - case RPG__STATIC: - case FIRELASER__STATIC: - case SPIT__STATIC: - case COOLEXPLOSION1__STATIC: - return -1; - default: - break; - } - } - } - - int const spriteAng = pSprite->ang; - - int isShrinker = (!RR && pSprite->picnum == TILE_APLAYER && g_player[playerNum].ps->curr_weapon == SHRINKER_WEAPON); - int isFreezer = (!RR && pSprite->picnum == TILE_APLAYER && g_player[playerNum].ps->curr_weapon == FREEZE_WEAPON); - - if (WW2GI) - { - isShrinker = (pSprite->picnum == TILE_APLAYER && PWEAPON(playerNum, g_player[playerNum].ps->curr_weapon, WorksLike) == SHRINKER_WEAPON); - isFreezer = (pSprite->picnum == TILE_APLAYER && PWEAPON(playerNum, g_player[playerNum].ps->curr_weapon, WorksLike) == FREEZE_WEAPON); - } - - vec2_t const d1 = { sintable[(spriteAng + 512 - projAng) & 2047], sintable[(spriteAng - projAng) & 2047] }; - vec2_t const d2 = { sintable[(spriteAng + 512 + projAng) & 2047], sintable[(spriteAng + projAng) & 2047] }; - vec2_t const d3 = { sintable[(spriteAng + 512) & 2047], sintable[spriteAng & 2047] }; - - int lastDist = INT32_MAX; - int bestSprite = -1; - - for (bssize_t k=0; k<4; k++) - { - if (bestSprite >= 0) - break; - - for (bssize_t spriteNum=headspritestat[aimstats[k]]; spriteNum >= 0; spriteNum=nextspritestat[spriteNum]) - { - if ((sprite[spriteNum].xrepeat > 0 && sprite[spriteNum].extra >= 0 && - (sprite[spriteNum].cstat & (257 + 32768)) == 257) && - (A_CheckEnemySprite(&sprite[spriteNum]) || k < 2)) - { - if (A_CheckEnemySprite(&sprite[spriteNum]) || PN(spriteNum) == TILE_APLAYER) - { - if (PN(spriteNum) == TILE_APLAYER && pSprite->picnum == TILE_APLAYER && pSprite != &sprite[spriteNum] && - (GTFLAGS(GAMETYPE_PLAYERSFRIENDLY) || - (GTFLAGS(GAMETYPE_TDM) && g_player[P_Get(spriteNum)].ps->team == g_player[playerNum].ps->team))) - continue; - - if ((isShrinker && sprite[spriteNum].xrepeat < 30 - && (PN(spriteNum) == TILE_SHARK || !(!RR && PN(spriteNum) >= TILE_GREENSLIME && PN(spriteNum) <= TILE_GREENSLIME + 7))) - || (isFreezer && sprite[spriteNum].pal == 1)) - continue; - } - - vec2_t const vd = { (SX(spriteNum) - pSprite->x), (SY(spriteNum) - pSprite->y) }; - - if ((d1.y * vd.x <= d1.x * vd.y) && (d2.y * vd.x >= d2.x * vd.y)) - { - int const spriteDist = mulscale14(d3.x, vd.x) + mulscale14(d3.y, vd.y); - - if (spriteDist > 512 && spriteDist < lastDist) - { - int onScreen = 1; - - if (pSprite->picnum == TILE_APLAYER) - { - const DukePlayer_t *const ps = g_player[P_GetP(pSprite)].ps; - onScreen = (klabs(scale(SZ(spriteNum)-pSprite->z,10,spriteDist)-fix16_to_int(ps->q16horiz+ps->q16horizoff-F16(100))) < 100); - } - - int const zOffset = (!RR && (PN(spriteNum) == TILE_ORGANTIC || PN(spriteNum) == TILE_ROTATEGUN)) ? 0 : ZOFFSET5; - int const canSee = cansee(SX(spriteNum), SY(spriteNum), SZ(spriteNum) - zOffset, SECT(spriteNum), - pSprite->x, pSprite->y, pSprite->z - ZOFFSET5, pSprite->sectnum); - - if (onScreen && canSee) - { - lastDist = spriteDist; - bestSprite = spriteNum; - } - } - } - } - } - } - - return bestSprite; -} - -static int CheckShootSwitchTile(int tileNum) -{ - return tileNum == TILE_DIPSWITCH || tileNum == TILE_DIPSWITCH + 1 || tileNum == TILE_DIPSWITCH2 || tileNum == TILE_DIPSWITCH2 + 1 || - tileNum == TILE_DIPSWITCH3 || tileNum == TILE_DIPSWITCH3 + 1 || tileNum == TILE_HANDSWITCH || tileNum == TILE_HANDSWITCH + 1 || - (RRRA && tileNum == TILE_RRTILE8660); -} - -static int32_t safeldist(int32_t spriteNum, const void *pSprite) -{ - int32_t distance = ldist(&sprite[spriteNum], (const spritetype*)pSprite); - return distance ? distance : 1; -} - -// flags: -// 1: do sprite center adjustment (cen-=(8<<8)) for TILE_GREENSLIME or TILE_ROTATEGUN -// 2: do auto getangle only if not TILE_RECON (if clear, do unconditionally) -static int GetAutoAimAng(int spriteNum, int playerNum, int projecTile, int zAdjust, int aimFlags, - const vec3_t *startPos, int projVel, int32_t *pZvel, int *pAng) -{ - int returnSprite = -1; - - Bassert((unsigned)playerNum < MAXPLAYERS); - - SetGameVarID(g_iAimAngleVarID, (g_player[playerNum].ps->auto_aim == 3 && (!RRRA || projecTile != TILE_RPG2)) ? AUTO_AIM_ANGLE<<1 : AUTO_AIM_ANGLE, spriteNum, playerNum); - - VM_OnEvent(EVENT_GETAUTOAIMANGLE, spriteNum, playerNum); - - int aimang = GetGameVarID(g_iAimAngleVarID, spriteNum, playerNum); - if (aimang > 0) - returnSprite = A_FindTargetSprite(&sprite[spriteNum], aimang, projecTile); - - if (returnSprite >= 0) - { - const uspritetype *const pSprite = (uspritetype *)&sprite[returnSprite]; - int zCenter = 2 * (pSprite->xrepeat * tilesiz[pSprite->picnum].y) + zAdjust; - - if ((aimFlags&1) && !RR && - ((pSprite->picnum >= TILE_GREENSLIME && pSprite->picnum <= TILE_GREENSLIME + 7) || pSprite->picnum == TILE_ROTATEGUN)) - zCenter -= ZOFFSET3; - - int spriteDist = safeldist(g_player[playerNum].ps->i, &sprite[returnSprite]); - *pZvel = tabledivide32_noinline((pSprite->z - startPos->z - zCenter) * projVel, spriteDist); - - if (!(aimFlags&2) || sprite[returnSprite].picnum != TILE_RECON) - *pAng = getangle(pSprite->x-startPos->x, pSprite->y-startPos->y); - } - - return returnSprite; -} - -static void Proj_MaybeAddSpread(int doSpread, int32_t *zvel, int *shootAng, int zRange, int angRange) -{ - if (doSpread) - { - // Ranges <= 1 mean no spread at all. A range of 1 calls krand2() though. - if (zRange > 0) - *zvel += (zRange >> 1) - krand2() % zRange; - - if (angRange > 0) - *shootAng += (angRange >> 1) - krand2() % angRange; - } -} - -static void Proj_MaybeAddSpreadSwapped(int doSpread, int32_t *zvel, int *shootAng, int zRange, int angRange) -{ - if (doSpread) - { - // Ranges <= 1 mean no spread at all. A range of 1 calls krand2() though. - if (angRange > 0) - *shootAng += (angRange >> 1) - krand2() % angRange; - - if (zRange > 0) - *zvel += (zRange >> 1) - krand2() % zRange; - } -} - -// Prepare hitscan weapon fired from player p. -static void P_PreFireHitscan(int spriteNum, int playerNum, int projecTile, vec3_t *srcVect, int32_t *zvel, int *shootAng, - int accurateAim, int doSpread) -{ - int angRange = (RR && projecTile == TILE_SHOTGUN) ? 128 : 32; - int zRange = 256; - int aimSprite = GetAutoAimAng(spriteNum, playerNum, projecTile, 5 << 8, 0 + 1, srcVect, 256, zvel, shootAng); - - DukePlayer_t *const pPlayer = g_player[playerNum].ps; - - SetGameVarID(g_iAngRangeVarID, angRange, spriteNum, playerNum); - SetGameVarID(g_iZRangeVarID, zRange, spriteNum, playerNum); - - VM_OnEvent(EVENT_GETSHOTRANGE, spriteNum, playerNum); - - angRange = GetGameVarID(g_iAngRangeVarID, spriteNum, playerNum); - zRange = GetGameVarID(g_iZRangeVarID, spriteNum, playerNum); - - if (accurateAim) - { - if (!pPlayer->auto_aim) - { - hitdata_t hitData; - - *zvel = fix16_to_int(F16(100)-pPlayer->q16horiz-pPlayer->q16horizoff)<<5; - - hitscan(srcVect, sprite[spriteNum].sectnum, sintable[(*shootAng + 512) & 2047], - sintable[*shootAng & 2047], *zvel << 6, &hitData, CLIPMASK1); - - if (hitData.sprite != -1) - { - int const statNumMap = ((1 << STAT_ACTOR) | (1 << STAT_ZOMBIEACTOR) | (1 << STAT_PLAYER) | (1 << STAT_DUMMYPLAYER)); - int const statNum = sprite[hitData.sprite].statnum; - - if ((unsigned)statNum <= 30 && (statNumMap & (1 << statNum))) - aimSprite = hitData.sprite; - } - } - - if (aimSprite == -1) - goto notarget; - } - else - { - if (aimSprite == -1) // no target - { -notarget: - *zvel = fix16_to_int(F16(100)-pPlayer->q16horiz-pPlayer->q16horizoff)<<5; - } - - Proj_MaybeAddSpreadSwapped(doSpread, zvel, shootAng, zRange, angRange); - } - - srcVect->z -= (2<<8); -} - -// Hitscan weapon fired from actor (sprite s); -static void A_PreFireHitscan(const spritetype *pSprite, vec3_t * const srcVect, int32_t * const zvel, int * const shootAng, int const doSpread) -{ - int const playerNum = findplayer(pSprite, NULL); - const DukePlayer_t *pPlayer = g_player[playerNum].ps; - int const playerDist = safeldist(pPlayer->i, pSprite); - - srcVect->z -= ZOFFSET6; - - *zvel = tabledivide32_noinline((pPlayer->pos.z - srcVect->z) << 8, playerDist); - - if (pSprite->picnum == TILE_BOSS1) - *shootAng = getangle(pPlayer->pos.x - srcVect->x, pPlayer->pos.y - srcVect->y); - - Proj_MaybeAddSpread(doSpread, zvel, shootAng, 256, 128 >> (uint8_t)(pSprite->picnum != TILE_BOSS1)); -} - -static int Proj_DoHitscan(int spriteNum, int32_t const cstatmask, const vec3_t * const srcVect, int zvel, int const shootAng, hitdata_t * const hitData) -{ - spritetype *const pSprite = &sprite[spriteNum]; - - pSprite->cstat &= ~cstatmask; - hitscan(srcVect, pSprite->sectnum, sintable[(shootAng + 512) & 2047], sintable[shootAng & 2047], zvel << 6, hitData, CLIPMASK1); - - if (RRRA) - { - if (((sector[hitData->sect].lotag == 160 && zvel > 0) || (sector[hitData->sect].lotag == 161 && zvel < 0)) - && hitData->sprite == -1 && hitData->wall == -1) - { - for (int spriteNum = 0; spriteNum < MAXSPRITES; spriteNum++) - { - if (sprite[spriteNum].sectnum == hitData->sect && sprite[spriteNum].picnum == TILE_SECTOREFFECTOR - && sprite[spriteNum].lotag == SE_7_TELEPORT) - { - vec3_t const newVect = { - hitData->pos.x + (sprite[OW(spriteNum)].x - sprite[spriteNum].x), - hitData->pos.y + (sprite[OW(spriteNum)].y - sprite[spriteNum].y), - sector[hitData->sect].lotag == 161 ? sector[sprite[OW(spriteNum)].sectnum].floorz - : sector[sprite[OW(spriteNum)].sectnum].ceilingz - }; - - hitscan(&newVect, sprite[OW(spriteNum)].sectnum, sintable[(shootAng + 512) & 2047], sintable[shootAng & 2047], zvel << 6, - hitData, CLIPMASK1); - break; - } - } - } - } - pSprite->cstat |= cstatmask; - - return (hitData->sect < 0); -} - -static int SectorContainsSE13(int const sectNum) -{ - if (sectNum >= 0) - { - for (bssize_t SPRITES_OF_SECT(sectNum, i)) - { - if (sprite[i].statnum == STAT_EFFECTOR && sprite[i].lotag == SE_13_EXPLOSIVE) - return 1; - } - } - return 0; -} - -// Maybe handle bit 2 (swap wall bottoms). -// (in that case walltype *hitwal may be stale) -static inline void HandleHitWall(hitdata_t *hitData) -{ - uwalltype const * const hitWall = (uwalltype *)&wall[hitData->wall]; - - if ((hitWall->cstat & 2) && redwallp(hitWall) && (hitData->pos.z >= sector[hitWall->nextsector].floorz)) - hitData->wall = hitWall->nextwall; -} - -// Common "spawn blood?" predicate. -// minzdiff: minimal "step" height for blood to be spawned -static int Proj_CheckBlood(vec3_t const *const srcVect, hitdata_t const *const hitData, int const bloodRange, int const minZdiff) -{ - if (hitData->wall < 0 || hitData->sect < 0) - return 0; - - uwalltype const *const hitWall = (uwalltype *)&wall[hitData->wall]; - - if ((FindDistance2D(srcVect->x - hitData->pos.x, srcVect->y - hitData->pos.y) < bloodRange) - && (hitWall->overpicnum != TILE_BIGFORCE && (hitWall->cstat & 16) == 0) - && (sector[hitData->sect].lotag == 0) - && (hitWall->nextsector < 0 || (sector[hitWall->nextsector].lotag == 0 && sector[hitData->sect].lotag == 0 - && sector[hitData->sect].floorz - sector[hitWall->nextsector].floorz > minZdiff))) - return 1; - - return 0; -} - -int A_Shoot(int const spriteNum, int const projecTile) -{ - Bassert(projecTile >= 0); - - spritetype *const pSprite = &sprite[spriteNum]; - int const spriteSectnum = pSprite->sectnum; - int const playerNum = (pSprite->picnum == TILE_APLAYER) ? P_GetP(pSprite) : -1; - DukePlayer_t *const pPlayer = playerNum >= 0 ? g_player[playerNum].ps : NULL; - int32_t Zvel = 0; - - hitdata_t hitData; - int shootAng; - vec3_t startPos; - int vel; - - if (pPlayer != NULL) - { - startPos = *(vec3_t *)pPlayer; - startPos.z += pPlayer->pyoff + ZOFFSET6; - shootAng = fix16_to_int(pPlayer->q16ang); - if (!RRRA) - pPlayer->crack_time = 777; - } - else - { - shootAng = pSprite->ang; - startPos = *(vec3_t *)pSprite; - startPos.z -= (((pSprite->yrepeat * tilesiz[pSprite->picnum].y)<<1) - ZOFFSET6); - - if (RR || pSprite->picnum != TILE_ROTATEGUN) - { - startPos.z -= (7<<8); - - if (A_CheckEnemySprite(pSprite) && (RR || PN(spriteNum) != TILE_COMMANDER)) - { - startPos.x += (sintable[(shootAng+1024+96)&2047]>>7); - startPos.y += (sintable[(shootAng+512+96)&2047]>>7); - } - } - -#ifdef POLYMER - switch (DYNAMICTILEMAP(projecTile)) - { - case FIRELASER__STATIC: - case SHOTGUN__STATIC: - case SHOTSPARK1__STATIC: - case CHAINGUN__STATIC: - case RPG__STATIC: - case MORTER__STATIC: - { - vec2_t const v = { ((sintable[(pSprite->ang + 512) & 2047]) >> 7), - ((sintable[(pSprite->ang) & 2047]) >> 7) }; - - pSprite->x += v.x; - pSprite->y += v.y; - G_AddGameLight(0, spriteNum, PHEIGHT, 8192, 255 + (95 << 8), PR_LIGHT_PRIO_MAX_GAME); - actor[spriteNum].lightcount = 2; - pSprite->x -= v.x; - pSprite->y -= v.y; - } - - break; - } -#endif // POLYMER - } - - switch (DYNAMICTILEMAP(projecTile)) - { - case BLOODSPLAT1__STATIC: - case BLOODSPLAT2__STATIC: - case BLOODSPLAT3__STATIC: - case BLOODSPLAT4__STATIC: - shootAng += 64 - (krand2() & 127); - if (playerNum < 0) - shootAng += 1024; - Zvel = 1024 - (krand2() & 2047); - fallthrough__; - case KNEE__STATIC: - case SLINGBLADE__STATICRR: - if (RR && !RRRA && projecTile == TILE_SLINGBLADE) - break; -growspark_rr: - if (projecTile == TILE_KNEE || (RR && projecTile == TILE_GROWSPARK) || (RRRA && projecTile == TILE_SLINGBLADE)) - { - if (playerNum >= 0) - { - Zvel = fix16_to_int(F16(100) - pPlayer->q16horiz - pPlayer->q16horizoff) << 5; - startPos.z += (6 << 8); - shootAng += 15; - } - else - { - int32_t playerDist; - int const playerSprite = g_player[findplayer(pSprite, &playerDist)].ps->i; - Zvel = tabledivide32_noinline((sprite[playerSprite].z - startPos.z) << 8, playerDist + 1); - shootAng = getangle(sprite[playerSprite].x - startPos.x, sprite[playerSprite].y - startPos.y); - } - } - - Proj_DoHitscan(spriteNum, 0, &startPos, Zvel, shootAng, &hitData); - - if (projecTile >= TILE_BLOODSPLAT1 && projecTile <= TILE_BLOODSPLAT4) - { - if (Proj_CheckBlood(&startPos, &hitData, 1024, 16 << 8)) - { - const uwalltype *const hitwal = (uwalltype *)&wall[hitData.wall]; - - if (SectorContainsSE13(hitwal->nextsector)) - return -1; - - if (hitwal->nextwall >= 0 && wall[hitwal->nextwall].hitag != 0) - return -1; - - if (hitwal->hitag == 0) - { - int const spawnedSprite = fi.spawn(spriteNum, projecTile); - sprite[spawnedSprite].xvel = -12; - sprite[spawnedSprite].ang - = (getangle(hitwal->x - wall[hitwal->point2].x, hitwal->y - wall[hitwal->point2].y) + 512) & 2047; - *(vec3_t *)&sprite[spawnedSprite] = hitData.pos; - sprite[spawnedSprite].cstat |= (krand2() & 4); - A_SetSprite(spawnedSprite, CLIPMASK0); - setsprite(spawnedSprite, (vec3_t *)&sprite[spawnedSprite]); - if (PN(spriteNum) == TILE_OOZFILTER || (!RR && PN(spriteNum) == TILE_NEWBEAST)) - sprite[spawnedSprite].pal = 6; - } - } - - return -1; - } - - if (hitData.sect < 0) - break; - - if (klabs(startPos.x - hitData.pos.x) + klabs(startPos.y - hitData.pos.y) < 1024) - { - if (hitData.wall >= 0 || hitData.sprite >= 0) - { - int kneeSprite = A_InsertSprite(hitData.sect, hitData.pos.x, hitData.pos.y, hitData.pos.z, - (RRRA && projecTile == TILE_SLINGBLADE) ? TILE_SLINGBLADE : TILE_KNEE,-15,0,0,shootAng,32,0,spriteNum,4); - sprite[kneeSprite].extra += (RRRA && projecTile == TILE_SLINGBLADE) ? 50 : (krand2()&7); - - if (playerNum >= 0) - { - int k = fi.spawn(kneeSprite, TILE_SMALLSMOKE); - sprite[k].z -= ZOFFSET3; - if (!RR || projecTile == TILE_KNEE) - A_PlaySound(KICK_HIT, kneeSprite); - else if (RRRA && projecTile == TILE_SLINGBLADE) - A_PlaySound(260, kneeSprite); - } - - if (pPlayer != NULL && pPlayer->inv_amount[GET_STEROIDS] > 0 && pPlayer->inv_amount[GET_STEROIDS] < 400) - sprite[kneeSprite].extra += (max_player_health>>2); - - if (hitData.sprite >= 0 && sprite[hitData.sprite].picnum != TILE_ACCESSSWITCH && sprite[hitData.sprite].picnum != TILE_ACCESSSWITCH2) - { - fi.checkhitsprite(hitData.sprite, kneeSprite); - if (playerNum >= 0) - fi.checkhitswitch(playerNum, hitData.sprite, 1); - } - else if (hitData.wall >= 0) - { - HandleHitWall(&hitData); - - if (hitData.wall >= 0 && wall[hitData.wall].picnum != TILE_ACCESSSWITCH && wall[hitData.wall].picnum != TILE_ACCESSSWITCH2) - { - fi.checkhitwall(kneeSprite, hitData.wall, hitData.pos.x, hitData.pos.y, hitData.pos.z, projecTile); - if (playerNum >= 0) - fi.checkhitswitch(playerNum, hitData.wall, 0); - } - } - } - else if(playerNum >= 0 && hitData.pos.z > 0 && sector[hitData.sect].lotag == 1) - { - int splashSprite = fi.spawn(pPlayer->i, TILE_WATERSPLASH2); - sprite[splashSprite].x = hitData.pos.x; - sprite[splashSprite].y = hitData.pos.y; - sprite[splashSprite].ang = fix16_to_int(pPlayer->q16ang); // Total tweek - sprite[splashSprite].xvel = 32; - A_SetSprite(spriteNum, RR ? 0 : CLIPMASK0); - sprite[splashSprite].xvel = 0; - } - } - break; - - case SHOTSPARK1__STATIC: - case SHOTGUN__STATIC: - case CHAINGUN__STATIC: - { - if (pSprite->extra >= 0) - pSprite->shade = -96; - - if (playerNum >= 0) - P_PreFireHitscan(spriteNum, playerNum, projecTile, &startPos, &Zvel, &shootAng, - projecTile == TILE_SHOTSPARK1 && !WW2GI, 1); - else - A_PreFireHitscan(pSprite, &startPos, &Zvel, &shootAng, 1); - - if (Proj_DoHitscan(spriteNum, 256 + 1, &startPos, Zvel, shootAng, &hitData)) - return -1; - - if (RR && projecTile == TILE_SHOTGUN && sector[hitData.sect].lotag == ST_1_ABOVE_WATER && (krand2()&1) != 0) - return -1; - - if ((krand2() & 15) == 0 && sector[hitData.sect].lotag == ST_2_UNDERWATER) - Proj_DoWaterTracers(hitData.pos, &startPos, 8 - (ud.multimode >> 1), pSprite->sectnum); - - int spawnedSprite; - - if (playerNum >= 0) - { - spawnedSprite = A_InsertSprite(hitData.sect, hitData.pos.x, hitData.pos.y, hitData.pos.z, TILE_SHOTSPARK1, -15, 10, 10, shootAng, 0, 0, spriteNum, 4); - sprite[spawnedSprite].extra = G_DefaultActorHealth(projecTile); - sprite[spawnedSprite].extra += (krand2()%6); - - - if (hitData.wall == -1 && hitData.sprite == -1) - { - if (Zvel < 0) - { - if (sector[hitData.sect].ceilingstat & 1) - { - sprite[spawnedSprite].xrepeat = 0; - sprite[spawnedSprite].yrepeat = 0; - return -1; - } - else - fi.checkhitceiling(hitData.sect); - } - - if (!RR || sector[hitData.sect].lotag != ST_1_ABOVE_WATER) - fi.spawn(spawnedSprite, TILE_SMALLSMOKE); - } - - if (hitData.sprite >= 0) - { - if (RR && sprite[hitData.sprite].picnum == TILE_TORNADO) - return -1; - fi.checkhitsprite(hitData.sprite, spawnedSprite); - - if (sprite[hitData.sprite].picnum == TILE_APLAYER && - (ud.ffire == 1 || (!GTFLAGS(GAMETYPE_PLAYERSFRIENDLY) && GTFLAGS(GAMETYPE_TDM) && - g_player[P_Get(hitData.sprite)].ps->team != g_player[P_Get(spriteNum)].ps->team))) - { - int jibSprite = fi.spawn(spawnedSprite, TILE_JIBS6); - - sprite[spawnedSprite].xrepeat = sprite[spawnedSprite].yrepeat = 0; - sprite[jibSprite].z += ZOFFSET6; - sprite[jibSprite].xvel = 16; - sprite[jibSprite].xrepeat = sprite[jibSprite].yrepeat = 24; - sprite[jibSprite].ang += 64 - (krand2() & 127); - } - else - { - fi.spawn(spawnedSprite, TILE_SMALLSMOKE); - } - - if (playerNum >= 0 && CheckShootSwitchTile(sprite[hitData.sprite].picnum)) - { - fi.checkhitswitch(playerNum, hitData.sprite, 1); - return -1; - } - } - else if (hitData.wall >= 0) - { - uwalltype const * const hitWall = (uwalltype *)&wall[hitData.wall]; - - fi.spawn(spawnedSprite, TILE_SMALLSMOKE); - - if (fi.isadoorwall(hitWall->picnum) == 1) - goto SKIPBULLETHOLE; - - if (RR && isablockdoor(hitWall->picnum) == 1) - goto SKIPBULLETHOLE; - - if (playerNum >= 0 && CheckShootSwitchTile(hitWall->picnum)) - { - fi.checkhitswitch(playerNum, hitData.wall, 0); - return -1; - } - - if (hitWall->hitag != 0 || (hitWall->nextwall >= 0 && wall[hitWall->nextwall].hitag != 0)) - goto SKIPBULLETHOLE; - - if ((hitData.sect >= 0 && sector[hitData.sect].lotag == 0) && - (hitWall->overpicnum != TILE_BIGFORCE && (hitWall->cstat & 16) == 0) && - ((hitWall->nextsector >= 0 && sector[hitWall->nextsector].lotag == 0) || (hitWall->nextsector == -1 && sector[hitData.sect].lotag == 0))) - { - int decalSprite; - - if (SectorContainsSE13(hitWall->nextsector)) - goto SKIPBULLETHOLE; - - for (SPRITES_OF(STAT_MISC, decalSprite)) - if (sprite[decalSprite].picnum == TILE_BULLETHOLE && dist(&sprite[decalSprite], &sprite[spawnedSprite]) < (12 + (krand2() & 7))) - goto SKIPBULLETHOLE; - - decalSprite = fi.spawn(spawnedSprite, TILE_BULLETHOLE); - - sprite[decalSprite].xvel = -1; - sprite[decalSprite].ang - = (getangle(hitWall->x - wall[hitWall->point2].x, hitWall->y - wall[hitWall->point2].y) + 512) & 2047; - - A_SetSprite(decalSprite, CLIPMASK0); - } - - SKIPBULLETHOLE: - - HandleHitWall(&hitData); - fi.checkhitwall(spawnedSprite, hitData.wall, hitData.pos.x, hitData.pos.y, hitData.pos.z, TILE_SHOTSPARK1); - } - } - else - { - spawnedSprite = A_InsertSprite(hitData.sect, hitData.pos.x, hitData.pos.y, hitData.pos.z, TILE_SHOTSPARK1, -15, 24, 24, shootAng, 0, 0, spriteNum, 4); - sprite[spawnedSprite].extra = G_DefaultActorHealth(projecTile); - - if (hitData.sprite >= 0) - { - fi.checkhitsprite(hitData.sprite, spawnedSprite); - if (sprite[hitData.sprite].picnum != TILE_APLAYER) - fi.spawn(spawnedSprite, TILE_SMALLSMOKE); - else - { - sprite[spawnedSprite].xrepeat = 0; - sprite[spawnedSprite].yrepeat = 0; - } - } - else if (hitData.wall >= 0) - fi.checkhitwall(spawnedSprite, hitData.wall, hitData.pos.x, hitData.pos.y, hitData.pos.z, TILE_SHOTSPARK1); - } - - if ((krand2() & 255) < (RR ? 10 : 4)) - S_PlaySound3D(PISTOL_RICOCHET, spawnedSprite, &hitData.pos); - - return -1; - } - - case TRIPBOMBSPRITE__STATIC: - { - if (!RR) break; - int const newSprite = fi.spawn(spriteNum, projecTile); - sprite[newSprite].xvel = 32; - sprite[newSprite].ang = sprite[spriteNum].ang; - sprite[newSprite].z -= (5<<8); - break; - } - - case BOWLINGBALL__STATICRR: - { - int const newSprite = fi.spawn(spriteNum, projecTile); - sprite[newSprite].xvel = 250; - sprite[newSprite].ang = sprite[spriteNum].ang; - sprite[newSprite].z -= (15<<8); - break; - } - - case OWHIP__STATICRR: - case UWHIP__STATICRR: - { - if (pSprite->extra >= 0) - pSprite->shade = -96; - - if (projecTile == TILE_OWHIP) - { - vel = 300; - startPos.z -= (15<<8); - } - else //if (projecTile == TILE_UWHIP) - { - vel = 300; - startPos.z += (4<<8); - } - - if (playerNum >= 0) - { - if (GetAutoAimAng(spriteNum, playerNum, projecTile, -ZOFFSET4, 0, &startPos, vel, &Zvel, &shootAng) < 0) - Zvel = fix16_to_int(F16(100) - pPlayer->q16horiz - pPlayer->q16horizoff) * 98; - } - else - { - int const otherPlayer = findplayer(pSprite, NULL); - if (pSprite->picnum == TILE_VIXEN) - shootAng -= krand2()&16; - else - shootAng += 16 - (krand2() & 31); - hitData.pos.x = safeldist(g_player[otherPlayer].ps->i, pSprite); - Zvel = tabledivide32_noinline((g_player[otherPlayer].ps->opos.z - startPos.z + (3 << 8)) * vel, hitData.pos.x); - } - - int spriteSize = (playerNum >= 0) ? 7 : 8; - - int const returnSprite = A_InsertSprite(spriteSectnum, startPos.x, startPos.y, startPos.z, projecTile, -127, spriteSize, spriteSize, - shootAng, vel, Zvel, spriteNum, 4); - - sprite[returnSprite].extra += (krand2() & 7); - - sprite[returnSprite].cstat = 128; - sprite[returnSprite].clipdist = 4; - - shootAng = pSprite->ang + 32 - (krand2() & 63); - Zvel += 512 - (krand2() & 1023); - - return returnSprite; - } - - - case GROWSPARK__STATIC: - { - if (RR) - goto growspark_rr; - if (playerNum >= 0) - P_PreFireHitscan(spriteNum, playerNum, projecTile, &startPos, &Zvel, &shootAng, 1, 1); - else - A_PreFireHitscan(pSprite, &startPos, &Zvel, &shootAng, 1); - - if (Proj_DoHitscan(spriteNum, 256 + 1, &startPos, Zvel, shootAng, &hitData)) - return -1; - - int const otherSprite = A_InsertSprite(hitData.sect, hitData.pos.x, hitData.pos.y, hitData.pos.z, TILE_GROWSPARK, -16, 28, 28, - shootAng, 0, 0, spriteNum, 1); - - sprite[otherSprite].pal = 2; - sprite[otherSprite].cstat |= 130; - sprite[otherSprite].xrepeat = sprite[otherSprite].yrepeat = 1; - - if (hitData.wall == -1 && hitData.sprite == -1 && hitData.sect >= 0 - && Zvel < 0 && (sector[hitData.sprite].ceilingstat & 1) == 0) - { - fi.checkhitceiling(hitData.sect); - } - else if (hitData.sprite >= 0) - fi.checkhitsprite(hitData.sprite, otherSprite); - else if (hitData.wall >= 0 && wall[hitData.wall].picnum != TILE_ACCESSSWITCH && wall[hitData.wall].picnum != TILE_ACCESSSWITCH2) - fi.checkhitwall(otherSprite, hitData.wall, hitData.pos.x, hitData.pos.y, hitData.pos.z, projecTile); - } - break; - - case FIRELASER__STATIC: - case SPIT__STATIC: - case COOLEXPLOSION1__STATIC: - { - if ((!RRRA || projecTile != TILE_SPIT) && pSprite->extra >= 0) - pSprite->shade = -96; - - switch (projecTile) - { - case SPIT__STATIC: - if (RRRA && pSprite->picnum == TILE_MAMA) - vel = 600; - else - vel = RR ? 400 : 292; - break; - case COOLEXPLOSION1__STATIC: - if (!RR) - { - vel = (pSprite->picnum == TILE_BOSS2) ? 644 : 348; - startPos.z -= (4 << 7); - break; - } - fallthrough__; - case FIRELASER__STATIC: - default: - vel = 840; - startPos.z -= (4 << 7); - if (RR) - { - if (pSprite->picnum == TILE_HULK) - { - startPos.x += sintable[(pSprite->ang+512+256)&2047]>>6; - startPos.y += sintable[(pSprite->ang+256)&2047]>>6; - startPos.z += (12 << 8); - } - else if (pSprite->picnum == TILE_VIXEN) - startPos.z -= (12 << 8); - } - break; - } - - if (playerNum >= 0) - { - if (RR) - { - startPos.x += sintable[(pSprite->ang+512+160)&2047]>>7; - startPos.y += sintable[(pSprite->ang+160)&2047]>>7; - } - if (GetAutoAimAng(spriteNum, playerNum, projecTile, -ZOFFSET4, 0, &startPos, vel, &Zvel, &shootAng) < 0) - Zvel = fix16_to_int(F16(100) - pPlayer->q16horiz - pPlayer->q16horizoff) * 98; - } - else - { - int const otherPlayer = findplayer(pSprite, NULL); - if (RR) - { - if (pSprite->picnum == TILE_HULK) - shootAng -= krand2()&31; - else if (pSprite->picnum == TILE_VIXEN) - shootAng -= krand2()&16; - else if (pSprite->picnum != TILE_UFOBEAM) - shootAng += 16 - (krand2() & 31); - } - else - shootAng += 16 - (krand2() & 31); - hitData.pos.x = safeldist(g_player[otherPlayer].ps->i, pSprite); - Zvel = tabledivide32_noinline((g_player[otherPlayer].ps->opos.z - startPos.z + (3 << 8)) * vel, hitData.pos.x); - } - - int spriteSize = 18; - - if (RR) - { - if (projecTile == TILE_SPIT) - { - if (RRRA && pSprite->picnum == TILE_MAMA) - startPos.z -= (20 << 8); - else - startPos.z -= (10 << 8); - } - else if (projecTile == TILE_COOLEXPLOSION1) - spriteSize = 8; - } - else - { - if (projecTile == TILE_SPIT) - startPos.z -= (10 << 8); - } - - if (playerNum >= 0) spriteSize = 7; - - int const returnSprite = A_InsertSprite(spriteSectnum, startPos.x, startPos.y, startPos.z, projecTile, -127, spriteSize, spriteSize, - shootAng, vel, Zvel, spriteNum, 4); - - sprite[returnSprite].extra += (krand2() & 7); - - if (!RR && projecTile == TILE_COOLEXPLOSION1) - { - sprite[returnSprite].shade = 0; - - if (PN(spriteNum) == TILE_BOSS2) - { - int const saveXvel = sprite[returnSprite].xvel; - sprite[returnSprite].xvel = 1024; - A_SetSprite(returnSprite, CLIPMASK0); - sprite[returnSprite].xvel = saveXvel; - sprite[returnSprite].ang += 128 - (krand2() & 255); - } - } - - sprite[returnSprite].cstat = 128; - sprite[returnSprite].clipdist = 4; - - shootAng = pSprite->ang + 32 - (krand2() & 63); - Zvel += 512 - (krand2() & 1023); - - if (RR && projecTile == TILE_FIRELASER) - sprite[returnSprite].xrepeat = sprite[returnSprite].yrepeat = 8; - - return returnSprite; - } - - case FREEZEBLAST__STATIC: - startPos.z += (3 << 8); - fallthrough__; - case RPG__STATIC: - case RPG2__STATICRR: - case RRTILE1790__STATICRR: - case SHRINKSPARK__STATIC: - { - if (!RR && projecTile == TILE_SHRINKSPARK) break; - if (RR && !RRRA && (projecTile == TILE_RPG2 || projecTile == TILE_RRTILE1790)) break; - - int targetSprite = 0; - - // XXX: "CODEDUP" - if (pSprite->extra >= 0) - pSprite->shade = -96; - - vel = 644; - - int otherSprite = -1; - - if (playerNum >= 0) - { - // NOTE: otherSprite is a SPRITE_INDEX - otherSprite = GetAutoAimAng(spriteNum, playerNum, projecTile, 8 << 8, 0 + 2, &startPos, vel, &Zvel, &shootAng); - - if (RRRA && projecTile == TILE_RPG2 && otherSprite >= 0) - { - if (sprite[otherSprite].picnum == TILE_HEN || sprite[otherSprite].picnum == TILE_HENSTAYPUT) - targetSprite = pPlayer->i; - else - targetSprite = otherSprite; - } - - if (otherSprite < 0) - Zvel = fix16_to_int(F16(100) - pPlayer->q16horiz - pPlayer->q16horizoff) * 81; - - if (projecTile == TILE_RPG) - A_PlaySound(RPG_SHOOT, spriteNum); - else if (RRRA) - { - if (projecTile == TILE_RPG2) - A_PlaySound(244, spriteNum); - else if (projecTile == TILE_RRTILE1790) - A_PlaySound(94, spriteNum); - } - } - else - { - // NOTE: otherSprite is a player index - otherSprite = findplayer(pSprite, NULL); - shootAng = getangle(g_player[otherSprite].ps->opos.x - startPos.x, g_player[otherSprite].ps->opos.y - startPos.y); - if (PN(spriteNum) == TILE_BOSS3) - startPos.z -= ZOFFSET5; - else if (PN(spriteNum) == TILE_BOSS2) - { - vel += 128; - startPos.z += 24<<8; - } - - Zvel = tabledivide32_noinline((g_player[otherSprite].ps->opos.z - startPos.z) * vel, safeldist(g_player[otherSprite].ps->i, pSprite)); - - if (A_CheckEnemySprite(pSprite) && (AC_MOVFLAGS(pSprite, &actor[spriteNum]) & face_player_smart)) - shootAng = pSprite->ang + (krand2() & 31) - 16; - } - - //if (numplayers > 1 && g_netClient) - // return -1; - - if (RRRA && projecTile == TILE_RRTILE1790) - { - Zvel = -(10 << 8); - vel <<= 1; - } - - int const returnSprite = A_InsertSprite(spriteSectnum, startPos.x + (sintable[(348 + shootAng + 512) & 2047] / 448), - startPos.y + (sintable[(shootAng + 348) & 2047] / 448), startPos.z - (1 << 8), - projecTile, 0, 14, 14, shootAng, vel, Zvel, spriteNum, 4); - spritetype *const pReturn = &sprite[returnSprite]; - - if (RRRA) - { - if (projecTile == TILE_RRTILE1790) - { - pReturn->extra = 10; - pReturn->zvel = -(10 << 8); - } - else if (projecTile == TILE_RPG2) - { - pReturn->lotag = targetSprite; - pReturn->hitag = 0; - A_SpawnMultiple(returnSprite, TILE_MONEY, (krand2()&3)+1); - } - } - - pReturn->extra += (krand2() & 7); - if (projecTile != TILE_FREEZEBLAST) - pReturn->yvel = (playerNum >= 0 && otherSprite >= 0) ? otherSprite : -1; // RPG_YVEL - else - { - pReturn->yvel = numfreezebounces; - pReturn->xrepeat >>= 1; - pReturn->yrepeat >>= 1; - pReturn->zvel -= (2 << 4); - } - - if (playerNum == -1) - { - if (RR && PN(spriteNum) == TILE_HULK) - { - pReturn->xrepeat = 8; - pReturn->yrepeat = 8; - } - else if (!RR && PN(spriteNum) == TILE_BOSS3) - { - if (krand2() & 1) - { - pReturn->x -= sintable[shootAng & 2047] >> 6; - pReturn->y -= sintable[(shootAng + 1024 + 512) & 2047] >> 6; - pReturn->ang -= 8; - } - else - { - pReturn->x += sintable[shootAng & 2047] >> 6; - pReturn->y += sintable[(shootAng + 1024 + 512) & 2047] >> 6; - pReturn->ang += 4; - } - pReturn->xrepeat = 42; - pReturn->yrepeat = 42; - } - else if (!RR && PN(spriteNum) == TILE_BOSS2) - { - pReturn->x -= sintable[shootAng & 2047] / 56; - pReturn->y -= sintable[(shootAng + 1024 + 512) & 2047] / 56; - pReturn->ang -= 8 + (krand2() & 255) - 128; - pReturn->xrepeat = 24; - pReturn->yrepeat = 24; - } - else if (projecTile != TILE_FREEZEBLAST) - { - pReturn->xrepeat = 30; - pReturn->yrepeat = 30; - pReturn->extra >>= 2; - } - } - else if ((WW2GI ? PWEAPON(playerNum, g_player[playerNum].ps->curr_weapon, WorksLike) : g_player[playerNum].ps->curr_weapon) == DEVISTATOR_WEAPON) - { - pReturn->extra >>= 2; - pReturn->ang += 16 - (krand2() & 31); - pReturn->zvel += 256 - (krand2() & 511); - - if (g_player[playerNum].ps->hbomb_hold_delay) - { - pReturn->x -= sintable[shootAng & 2047] / 644; - pReturn->y -= sintable[(shootAng + 1024 + 512) & 2047] / 644; - } - else - { - pReturn->x += sintable[shootAng & 2047] >> 8; - pReturn->y += sintable[(shootAng + 1024 + 512) & 2047] >> 8; - } - pReturn->xrepeat >>= 1; - pReturn->yrepeat >>= 1; - } - - pReturn->cstat = 128; - pReturn->clipdist = (projecTile == TILE_RPG) ? 4 : 40; - - if (RRRA && (projecTile == TILE_RPG2 || projecTile == TILE_RRTILE1790)) - pReturn->clipdist = 4; - - return returnSprite; - } - - case HANDHOLDINGLASER__STATIC: - { - if (RR) break; - int const zOffset = (playerNum >= 0) ? g_player[playerNum].ps->pyoff : 0; - Zvel = (playerNum >= 0) ? fix16_to_int(F16(100) - pPlayer->q16horiz - pPlayer->q16horizoff) * 32 : 0; - - startPos.z -= zOffset; - Proj_DoHitscan(spriteNum, 0, &startPos, Zvel, shootAng, &hitData); - startPos.z += zOffset; - - int placeMine = 0; - if (hitData.sprite >= 0) - break; - - if (hitData.wall >= 0 && hitData.sect >= 0) - if (((hitData.pos.x - startPos.x) * (hitData.pos.x - startPos.x) - + (hitData.pos.y - startPos.y) * (hitData.pos.y - startPos.y)) - < (290 * 290)) - { - // ST_2_UNDERWATER - if (wall[hitData.wall].nextsector >= 0) - { - if (sector[wall[hitData.wall].nextsector].lotag <= 2 && sector[hitData.sect].lotag <= 2) - placeMine = 1; - } - else if (sector[hitData.sect].lotag <= 2) - placeMine = 1; - } - - if (placeMine == 1) - { - int const tripBombMode = GetGameVar("TRIPBOMB_CONTROL", TRIPBOMB_TRIPWIRE, -1, -1); - int const spawnedSprite = A_InsertSprite(hitData.sect, hitData.pos.x, hitData.pos.y, hitData.pos.z, TILE_TRIPBOMB, -16, 4, 5, - shootAng, 0, 0, spriteNum, 6); - if (tripBombMode & TRIPBOMB_TIMER) - { - int32_t lLifetime = GetGameVar("STICKYBOMB_LIFETIME", NAM_GRENADE_LIFETIME, -1, playerNum); - int32_t lLifetimeVar - = GetGameVar("STICKYBOMB_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, -1, playerNum); - // set timer. blows up when at zero.... - sprite[spawnedSprite].extra = lLifetime + mulscale14(krand2(), lLifetimeVar) - lLifetimeVar; - } - sprite[spawnedSprite].hitag = spawnedSprite; - A_PlaySound(LASERTRIP_ONWALL, spawnedSprite); - sprite[spawnedSprite].xvel = -20; - A_SetSprite(spawnedSprite, CLIPMASK0); - sprite[spawnedSprite].cstat = 16; - - int const p2 = wall[hitData.wall].point2; - int const wallAng = getangle(wall[hitData.wall].x - wall[p2].x, wall[hitData.wall].y - wall[p2].y) - 512; - - actor[spawnedSprite].t_data[5] = sprite[spawnedSprite].ang = wallAng; - - if (!WW2GI && playerNum >= 0) - pPlayer->ammo_amount[TRIPBOMB_WEAPON]--; - - return spawnedSprite; - } - return -1; - } - - case BOUNCEMINE__STATIC: - if (RR) break; - fallthrough__; - case MORTER__STATIC: - case CHEERBOMB__STATICRR: - { - if (RR && !RRRA && projecTile == TILE_CHEERBOMB) break; - - if (pSprite->extra >= 0) - pSprite->shade = -96; - - int const playerSprite = g_player[findplayer(pSprite, NULL)].ps->i; - int const playerDist = ldist(&sprite[playerSprite], pSprite); - - Zvel = -playerDist >> 1; - - if (Zvel < -4096) - Zvel = -2048; - - vel = playerDist >> 4; - - int spriteSize = (RRRA && projecTile == TILE_CHEERBOMB) ? 16 : 32; - - A_InsertSprite(spriteSectnum, startPos.x + (sintable[(512 + shootAng + 512) & 2047] >> 8), - startPos.y + (sintable[(shootAng + 512) & 2047] >> 8), startPos.z + (6 << 8), projecTile, -64, - spriteSize, spriteSize, shootAng, vel, Zvel, spriteNum, 1); - break; - } - - case SHRINKER__STATIC: - { - if (RR) break; - if (pSprite->extra >= 0) - pSprite->shade = -96; - - if (playerNum >= 0) - { - if (NAM_WW2GI || GetAutoAimAng(spriteNum, playerNum, projecTile, ZOFFSET6, 0, &startPos, 768, &Zvel, &shootAng) < 0) - Zvel = fix16_to_int(F16(100) - pPlayer->q16horiz - pPlayer->q16horizoff) * 98; - } - else if (pSprite->statnum != STAT_EFFECTOR) - { - int const otherPlayer = findplayer(pSprite, NULL); - Zvel = tabledivide32_noinline((g_player[otherPlayer].ps->opos.z - startPos.z) * 512, - safeldist(g_player[otherPlayer].ps->i, pSprite)); - } - else - Zvel = 0; - - int const returnSprite = A_InsertSprite(spriteSectnum, startPos.x + (sintable[(512 + shootAng + 512) & 2047] >> 12), - startPos.y + (sintable[(shootAng + 512) & 2047] >> 12), startPos.z + (2 << 8), - TILE_SHRINKSPARK, -16, 28, 28, shootAng, 768, Zvel, spriteNum, 4); - sprite[returnSprite].cstat = 128; - sprite[returnSprite].clipdist = 32; - - return returnSprite; - } - } - - return -1; -} void A_DHShoot(int const playerNum) {