diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 1a8f3f19a..381dddee7 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -128,6 +128,7 @@ void quickkill(struct player_struct* p); void setpal(struct player_struct* p); int madenoise(int playerNum); int haskey(int sect, int snum); +void shootbloodsplat(int i, int p, int sx, int sy, int sz, int sa, int atwith, int BIGFORCE, int OOZFILTER, int NEWBEAST); void breakwall(short newpn, short spr, short dawallnum); void callsound2(int soundNum, int playerNum); diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index a8c1d9b90..6d019cd7f 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -1048,6 +1048,76 @@ int haskey(int sect, int snum) return 0; } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void shootbloodsplat(int i, int p, int sx, int sy, int sz, int sa, int atwith, int BIGFORCE, int OOZFILTER, int NEWBEAST) +{ + spritetype* const s = &sprite[i]; + int sect = s->sectnum; + int zvel; + short hitsect, hitspr, hitwall, k; + int hitx, hity, hitz; + + if (p >= 0) + sa += 64 - (krand() & 127); + else sa += 1024 + 64 - (krand() & 127); + zvel = 1024 - (krand() & 2047); + + + hitscan(sx, sy, sz, sect, + sintable[(sa + 512) & 2047], + sintable[sa & 2047], zvel << 6, + &hitsect, &hitwall, &hitspr, &hitx, &hity, &hitz, CLIPMASK1); + + // oh my... + if (FindDistance2D(sx - hitx, sy - hity) < 1024 && + (hitwall >= 0 && wall[hitwall].overpicnum != BIGFORCE) && + ((wall[hitwall].nextsector >= 0 && hitsect >= 0 && + sector[wall[hitwall].nextsector].lotag == 0 && + sector[hitsect].lotag == 0 && + sector[wall[hitwall].nextsector].lotag == 0 && + (sector[hitsect].floorz - sector[wall[hitwall].nextsector].floorz) > (16 << 8)) || + (wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0))) + { + if ((wall[hitwall].cstat & 16) == 0) + { + if (wall[hitwall].nextsector >= 0) + { + SectIterator it(wall[hitwall].nextsector); + while ((k = it.NextIndex()) >= 0) + { + if (sprite[k].statnum == 3 && sprite[k].lotag == 13) + return; + } + } + + if (wall[hitwall].nextwall >= 0 && + wall[wall[hitwall].nextwall].hitag != 0) + return; + + if (wall[hitwall].hitag == 0) + { + k = fi.spawn(i, atwith); + sprite[k].xvel = -12; + sprite[k].ang = getangle(wall[hitwall].x - wall[wall[hitwall].point2].x, wall[hitwall].y - wall[wall[hitwall].point2].y) + 512; + sprite[k].x = hitx; + sprite[k].y = hity; + sprite[k].z = hitz; + sprite[k].cstat |= (krand() & 4); + ssp(k, CLIPMASK0); + setsprite(k, sprite[k].x, sprite[k].y, sprite[k].z); + if (s->picnum == OOZFILTER || s->picnum == NEWBEAST) + sprite[k].pal = 6; + } + } + } +} + + //--------------------------------------------------------------------------- // // view - as in third person view (stupid name for this function) diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index f670c6b3b..ee3b42faa 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -226,75 +226,6 @@ static void shootflamethrowerflame(int i, int p, int sx, int sy, int sz, int sa) // //--------------------------------------------------------------------------- -static void shootbloodsplat(int i, int p, int sx, int sy, int sz, int sa, int atwith) -{ - spritetype* const s = &sprite[i]; - int sect = s->sectnum; - int zvel; - short hitsect, hitspr, hitwall, k; - int hitx, hity, hitz; - - if (p >= 0) - sa += 64 - (krand() & 127); - else sa += 1024 + 64 - (krand() & 127); - zvel = 1024 - (krand() & 2047); - - - hitscan(sx, sy, sz, sect, - sintable[(sa + 512) & 2047], - sintable[sa & 2047], zvel << 6, - &hitsect, &hitwall, &hitspr, &hitx, &hity, &hitz, CLIPMASK1); - - // oh my... - if (FindDistance2D(sx - hitx, sy - hity) < 1024 && - (hitwall >= 0 && wall[hitwall].overpicnum != BIGFORCE) && - ((wall[hitwall].nextsector >= 0 && hitsect >= 0 && - sector[wall[hitwall].nextsector].lotag == 0 && - sector[hitsect].lotag == 0 && - sector[wall[hitwall].nextsector].lotag == 0 && - (sector[hitsect].floorz - sector[wall[hitwall].nextsector].floorz) > (16 << 8)) || - (wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0))) - { - if ((wall[hitwall].cstat & 16) == 0) - { - if (wall[hitwall].nextsector >= 0) - { - SectIterator it(wall[hitwall].nextsector); - while ((k = it.NextIndex()) >= 0) - { - if (sprite[k].statnum == 3 && sprite[k].lotag == 13) - return; - } - } - - if (wall[hitwall].nextwall >= 0 && - wall[wall[hitwall].nextwall].hitag != 0) - return; - - if (wall[hitwall].hitag == 0) - { - k = fi.spawn(i, atwith); - sprite[k].xvel = -12; - sprite[k].ang = getangle(wall[hitwall].x - wall[wall[hitwall].point2].x, wall[hitwall].y - wall[wall[hitwall].point2].y) + 512; - sprite[k].x = hitx; - sprite[k].y = hity; - sprite[k].z = hitz; - sprite[k].cstat |= (krand() & 4); - ssp(k, CLIPMASK0); - setsprite(k, sprite[k].x, sprite[k].y, sprite[k].z); - if (s->picnum == OOZFILTER || s->picnum == NEWBEAST) - sprite[k].pal = 6; - } - } - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - static void shootknee(int i, int p, int sx, int sy, int sz, int sa) { spritetype* const s = &sprite[i]; @@ -604,10 +535,8 @@ static void shootweapon(int i, int p, int sx, int sy, int sz, int sa, int atwith fi.spawn(k, SMALLSMOKE); else sprite[k].xrepeat = sprite[k].yrepeat = 0; } - else if (hitwall >= 0) { - + else if (hitwall >= 0) fi.checkhitwall(k, hitwall, hitx, hity, hitz, SHOTSPARK1); - } } if ((krand() & 255) < 4) @@ -1144,7 +1073,7 @@ void shoot_d(int i, int atwith) case BLOODSPLAT2: case BLOODSPLAT3: case BLOODSPLAT4: - shootbloodsplat(i, p, sx, sy, sz, sa, atwith); + shootbloodsplat(i, p, sx, sy, sz, sa, atwith, BIGFORCE, OOZFILTER, NEWBEAST); break; case KNEE: diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index e83b00018..8cd29a3e5 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -87,6 +87,754 @@ void incur_damage_r(struct player_struct* p) // //--------------------------------------------------------------------------- +static void shootmelee(int i, int p, int sx, int sy, int sz, int sa, int atwith) +{ + spritetype* const s = &sprite[i]; + int sect = s->sectnum; + int zvel; + short hitsect, hitspr, hitwall, j, k; + int hitx, hity, hitz; + + if (p >= 0) + { + zvel = -ps[p].horizon.sum().asq16() >> 11; + sz += (6 << 8); + sa += 15; + } + else + { + int x; + j = ps[findplayer(s, &x)].i; + zvel = ((sprite[j].z - sz) << 8) / (x + 1); + sa = getangle(sprite[j].x - sx, sprite[j].y - sy); + } + + hitscan(sx, sy, sz, sect, + sintable[(sa + 512) & 2047], + sintable[sa & 2047], zvel << 6, + &hitsect, &hitwall, &hitspr, &hitx, &hity, &hitz, CLIPMASK1); + + if (isRRRA() && ((sector[hitsect].lotag == 160 && zvel > 0) || (sector[hitsect].lotag == 161 && zvel < 0)) + && hitspr == -1 && hitwall == -1) + { + short ii; + for (ii = 0; ii < MAXSPRITES; ii++) + { + if (sprite[ii].sectnum == hitsect && sprite[ii].picnum == SECTOREFFECTOR + && sprite[ii].lotag == 7) + { + int nx, ny, nz; + nx = hitx + (sprite[sprite[ii].owner].x - sprite[ii].x); + ny = hity + (sprite[sprite[ii].owner].y - sprite[ii].y); + if (sector[hitsect].lotag == 161) + { + nz = sector[sprite[sprite[ii].owner].sectnum].floorz; + } + else + { + nz = sector[sprite[sprite[ii].owner].sectnum].ceilingz; + } + hitscan(nx, ny, nz, sprite[sprite[ii].owner].sectnum, + sintable[(sa + 512) & 2047], + sintable[sa & 2047], zvel << 6, + &hitsect, &hitwall, &hitspr, &hitx, &hity, &hitz, CLIPMASK1); + break; + } + } + } + + if (hitsect < 0) return; + + if ((abs(sx - hitx) + abs(sy - hity)) < 1024) + { + if (hitwall >= 0 || hitspr >= 0) + { + if (isRRRA() && atwith == SLINGBLADE) + { + j = EGS(hitsect, hitx, hity, hitz, SLINGBLADE, -15, 0, 0, sa, 32, 0, i, 4); + sprite[j].extra += 50; + } + else + { + j = EGS(hitsect, hitx, hity, hitz, KNEE, -15, 0, 0, sa, 32, 0, i, 4); + sprite[j].extra += (krand() & 7); + } + if (p >= 0) + { + k = fi.spawn(j, SMALLSMOKE); + sprite[k].z -= (8 << 8); + if (atwith == KNEE) + S_PlayActorSound(KICK_HIT, j); + else if (isRRRA() && atwith == SLINGBLADE) + S_PlayActorSound(260, j); + } + + if (p >= 0 && ps[p].steroids_amount > 0 && ps[p].steroids_amount < 400) + sprite[j].extra += (max_player_health >> 2); + + if (hitspr >= 0 && sprite[hitspr].picnum != ACCESSSWITCH && sprite[hitspr].picnum != ACCESSSWITCH2) + { + fi.checkhitsprite(hitspr, j); + if (p >= 0) fi.checkhitswitch(p, hitspr, 1); + } + else if (hitwall >= 0) + { + if (wall[hitwall].cstat & 2) + if (wall[hitwall].nextsector >= 0) + if (hitz >= (sector[wall[hitwall].nextsector].floorz)) + hitwall = wall[hitwall].nextwall; + + if (hitwall >= 0 && wall[hitwall].picnum != ACCESSSWITCH && wall[hitwall].picnum != ACCESSSWITCH2) + { + fi.checkhitwall(j, hitwall, hitx, hity, hitz, atwith); + if (p >= 0) fi.checkhitswitch(p, hitwall, 0); + } + } + } + else if (p >= 0 && zvel > 0 && sector[hitsect].lotag == 1) + { + j = fi.spawn(ps[p].i, WATERSPLASH2); + sprite[j].x = hitx; + sprite[j].y = hity; + sprite[j].ang = ps[p].angle.ang.asbuild(); // Total tweek + sprite[j].xvel = 32; + ssp(i, 0); + sprite[j].xvel = 0; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void shootweapon(int i, int p, int sx, int sy, int sz, int sa, int atwith) +{ + spritetype* const s = &sprite[i]; + int sect = s->sectnum; + int zvel; + short hitsect, hitspr, hitwall, l, j, k; + int hitx, hity, hitz; + + if (s->extra >= 0) s->shade = -96; + + if (p >= 0) + { + j = aim(s, AUTO_AIM_ANGLE); + if (j >= 0) + { + int dal = ((sprite[j].xrepeat * tilesiz[sprite[j].picnum].y) << 1) + (5 << 8); + zvel = ((sprite[j].z - sz - dal) << 8) / ldist(&sprite[ps[p].i], &sprite[j]); + sa = getangle(sprite[j].x - sx, sprite[j].y - sy); + } + + if (atwith == SHOTSPARK1) + { + if (j == -1) + { + sa += 16 - (krand() & 31); + zvel = -ps[p].horizon.sum().asq16() >> 11; + zvel += 128 - (krand() & 255); + } + } + else + { + if (atwith == SHOTGUN) + sa += 64 - (krand() & 127); + else + sa += 16 - (krand() & 31); + if (j == -1) zvel = -ps[p].horizon.sum().asq16() >> 11; + zvel += 128 - (krand() & 255); + } + sz -= (2 << 8); + } + else + { + int x; + j = findplayer(s, &x); + sz -= (4 << 8); + zvel = ((ps[j].posz - sz) << 8) / (ldist(&sprite[ps[j].i], s)); + if (s->picnum != BOSS1) + { + zvel += 128 - (krand() & 255); + sa += 32 - (krand() & 63); + } + else + { + zvel += 128 - (krand() & 255); + sa = getangle(ps[j].posx - sx, ps[j].posy - sy) + 64 - (krand() & 127); + } + } + + s->cstat &= ~257; + hitscan(sx, sy, sz, sect, + sintable[(sa + 512) & 2047], + sintable[sa & 2047], + zvel << 6, &hitsect, &hitwall, &hitspr, &hitx, &hity, &hitz, CLIPMASK1); + + if (isRRRA() && (((sector[hitsect].lotag == 160 && zvel > 0) || (sector[hitsect].lotag == 161 && zvel < 0)) + && hitspr == -1 && hitwall == -1)) + { + short ii; + for (ii = 0; ii < MAXSPRITES; ii++) + { + if (sprite[ii].sectnum == hitsect && sprite[ii].picnum == SECTOREFFECTOR + && sprite[ii].lotag == 7) + { + int nx, ny, nz; + nx = hitx + (sprite[sprite[ii].owner].x - sprite[ii].x); + ny = hity + (sprite[sprite[ii].owner].y - sprite[ii].y); + if (sector[hitsect].lotag == 161) + { + nz = sector[sprite[sprite[ii].owner].sectnum].floorz; + } + else + { + nz = sector[sprite[sprite[ii].owner].sectnum].ceilingz; + } + hitscan(nx, ny, nz, sprite[sprite[ii].owner].sectnum, + sintable[(sa + 512) & 2047], + sintable[sa & 2047], zvel << 6, + &hitsect, &hitwall, &hitspr, &hitx, &hity, &hitz, CLIPMASK1); + break; + } + } + } + + s->cstat |= 257; + + if (hitsect < 0) return; + + if (atwith == SHOTGUN) + if (sector[hitsect].lotag == 1) + if (krand() & 1) + return; + + if ((krand() & 15) == 0 && sector[hitsect].lotag == 2) + tracers(hitx, hity, hitz, sx, sy, sz, 8 - (ud.multimode >> 1)); + + if (p >= 0) + { + k = EGS(hitsect, hitx, hity, hitz, SHOTSPARK1, -15, 10, 10, sa, 0, 0, i, 4); + sprite[k].extra = ScriptCode[actorinfo[atwith].scriptaddress]; + sprite[k].extra += (krand() % 6); + + if (hitwall == -1 && hitspr == -1) + { + if (zvel < 0) + { + if (sector[hitsect].ceilingstat & 1) + { + sprite[k].xrepeat = 0; + sprite[k].yrepeat = 0; + return; + } + else + fi.checkhitceiling(hitsect); + } + if (sector[hitsect].lotag != 1) + fi.spawn(k, SMALLSMOKE); + } + + if (hitspr >= 0) + { + if (sprite[hitspr].picnum == 1930) + return; + fi.checkhitsprite(hitspr, k); + if (sprite[hitspr].picnum == TILE_APLAYER && (ud.coop != 1 || ud.ffire == 1)) + { + l = fi.spawn(k, JIBS6); + sprite[k].xrepeat = sprite[k].yrepeat = 0; + sprite[l].z += (4 << 8); + sprite[l].xvel = 16; + sprite[l].xrepeat = sprite[l].yrepeat = 24; + sprite[l].ang += 64 - (krand() & 127); + } + else fi.spawn(k, SMALLSMOKE); + + if (p >= 0 && ( + sprite[hitspr].picnum == DIPSWITCH || + sprite[hitspr].picnum == DIPSWITCH + 1 || + sprite[hitspr].picnum == DIPSWITCH2 || + sprite[hitspr].picnum == DIPSWITCH2 + 1 || + sprite[hitspr].picnum == DIPSWITCH3 || + sprite[hitspr].picnum == DIPSWITCH3 + 1 || + (isRRRA() && sprite[hitspr].picnum == RRTILE8660) || + sprite[hitspr].picnum == HANDSWITCH || + sprite[hitspr].picnum == HANDSWITCH + 1)) + { + fi.checkhitswitch(p, hitspr, 1); + return; + } + } + else if (hitwall >= 0) + { + fi.spawn(k, SMALLSMOKE); + + if (fi.isadoorwall(wall[hitwall].picnum) == 1) + goto SKIPBULLETHOLE; + if (isablockdoor(wall[hitwall].picnum) == 1) + goto SKIPBULLETHOLE; + if (p >= 0 && ( + wall[hitwall].picnum == DIPSWITCH || + wall[hitwall].picnum == DIPSWITCH + 1 || + wall[hitwall].picnum == DIPSWITCH2 || + wall[hitwall].picnum == DIPSWITCH2 + 1 || + wall[hitwall].picnum == DIPSWITCH3 || + wall[hitwall].picnum == DIPSWITCH3 + 1 || + (isRRRA() && wall[hitwall].picnum == RRTILE8660) || + wall[hitwall].picnum == HANDSWITCH || + wall[hitwall].picnum == HANDSWITCH + 1)) + { + fi.checkhitswitch(p, hitwall, 0); + return; + } + + if (wall[hitwall].hitag != 0 || (wall[hitwall].nextwall >= 0 && wall[wall[hitwall].nextwall].hitag != 0)) + goto SKIPBULLETHOLE; + + if (hitsect >= 0 && sector[hitsect].lotag == 0) + if (wall[hitwall].overpicnum != BIGFORCE) + if ((wall[hitwall].nextsector >= 0 && sector[wall[hitwall].nextsector].lotag == 0) || + (wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0)) + if ((wall[hitwall].cstat & 16) == 0) + { + if (wall[hitwall].nextsector >= 0) + { + SectIterator it(wall[hitwall].nextsector); + while ((l = it.NextIndex()) >= 0) + { + if (sprite[l].statnum == 3 && sprite[l].lotag == 13) + goto SKIPBULLETHOLE; + } + } + + StatIterator it(STAT_MISC); + while ((l = it.NextIndex()) >= 0) + { + if (sprite[l].picnum == BULLETHOLE) + if (dist(&sprite[l], &sprite[k]) < (12 + (krand() & 7))) + goto SKIPBULLETHOLE; + } + l = fi.spawn(k, BULLETHOLE); + sprite[l].xvel = -1; + sprite[l].ang = getangle(wall[hitwall].x - wall[wall[hitwall].point2].x, + wall[hitwall].y - wall[wall[hitwall].point2].y) + 512; + ssp(l, CLIPMASK0); + } + + SKIPBULLETHOLE: + + if (wall[hitwall].cstat & 2) + if (wall[hitwall].nextsector >= 0) + if (hitz >= (sector[wall[hitwall].nextsector].floorz)) + hitwall = wall[hitwall].nextwall; + + fi.checkhitwall(k, hitwall, hitx, hity, hitz, SHOTSPARK1); + } + } + else + { + k = EGS(hitsect, hitx, hity, hitz, SHOTSPARK1, -15, 24, 24, sa, 0, 0, i, 4); + sprite[k].extra = ScriptCode[actorinfo[atwith].scriptaddress]; + + if (hitspr >= 0) + { + fi.checkhitsprite(hitspr, k); + if (sprite[hitspr].picnum != TILE_APLAYER) + fi.spawn(k, SMALLSMOKE); + else sprite[k].xrepeat = sprite[k].yrepeat = 0; + } + else if (hitwall >= 0) + fi.checkhitwall(k, hitwall, hitx, hity, hitz, SHOTSPARK1); + } + + if ((krand() & 255) < 10) + { + vec3_t v{ hitx, hity, hitz }; + S_PlaySound3D(PISTOL_RICOCHET, k, &v); + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void shootstuff(int i, int p, int sx, int sy, int sz, int sa, int atwith) +{ + spritetype* const s = &sprite[i]; + int sect = s->sectnum; + int vel, zvel; + short l, j, scount; + + if (isRRRA()) + { + if (atwith != SPIT && s->extra >= 0) s->shade = -96; + + scount = 1; + if (atwith == SPIT) + { + if (s->picnum == 8705) + vel = 600; + else + vel = 400; + } + } + else + { + if (s->extra >= 0) s->shade = -96; + + scount = 1; + if (atwith == SPIT) vel = 400; + } + if (atwith != SPIT) + { + vel = 840; + sz -= (4 << 7); + if (s->picnum == 4649) + { + sx += sintable[(s->ang + 512 + 256) & 2047] >> 6; + sy += sintable[(s->ang + 256) & 2047] >> 6; + sz += (12 << 8); + } + if (s->picnum == VIXEN) + { + sz -= (12 << 8); + } + } + + if (p >= 0) + { + j = aim(s, AUTO_AIM_ANGLE); + + if (j >= 0) + { + sx += sintable[(s->ang + 512 + 160) & 2047] >> 7; + sy += sintable[(s->ang + 160) & 2047] >> 7; + int dal = ((sprite[j].xrepeat * tilesiz[sprite[j].picnum].y) << 1) - (12 << 8); + zvel = ((sprite[j].z - sz - dal) * vel) / ldist(&sprite[ps[p].i], &sprite[j]); + sa = getangle(sprite[j].x - sx, sprite[j].y - sy); + } + else + { + sx += sintable[(s->ang + 512 + 160) & 2047] >> 7; + sy += sintable[(s->ang + 160) & 2047] >> 7; + zvel = -mulscale16(ps[p].horizon.sum().asq16(), 98); + } + } + else + { + int x; + j = findplayer(s, &x); + // sa = getangle(ps[j].oposx-sx,ps[j].oposy-sy); + if (s->picnum == HULK) + sa -= (krand() & 31); + else if (s->picnum == VIXEN) + sa -= (krand() & 16); + else if (s->picnum != UFOBEAM) + sa += 16 - (krand() & 31); + + zvel = (((ps[j].oposz - sz + (3 << 8))) * vel) / ldist(&sprite[ps[j].i], s); + } + + int oldzvel = zvel; + int sizx, sizy; + + if (atwith == SPIT) + { + sizx = 18; sizy = 18; + if (!isRRRA() || s->picnum != MAMA) sz -= (10 << 8); else sz -= (20 << 8); + } + else + { + if (atwith == COOLEXPLOSION1) + { + sizx = 8; + sizy = 8; + } + else if (atwith == FIRELASER) + { + if (p >= 0) + { + + sizx = 34; + sizy = 34; + } + else + { + sizx = 18; + sizy = 18; + } + } + else + { + sizx = 18; + sizy = 18; + } + } + + if (p >= 0) sizx = 7, sizy = 7; + + while (scount > 0) + { + j = EGS(sect, sx, sy, sz, atwith, -127, sizx, sizy, sa, vel, zvel, i, 4); + sprite[j].extra += (krand() & 7); + sprite[j].cstat = 128; + sprite[j].clipdist = 4; + + sa = s->ang + 32 - (krand() & 63); + zvel = oldzvel + 512 - (krand() & 1023); + + if (atwith == FIRELASER) + { + sprite[j].xrepeat = 8; + sprite[j].yrepeat = 8; + } + + scount--; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void shootrpg(int i, int p, int sx, int sy, int sz, int sa, int atwith) +{ + spritetype* const s = &sprite[i]; + int sect = s->sectnum; + int vel, zvel; + short l, j, scount; + + short var90 = 0; + if (s->extra >= 0) s->shade = -96; + + scount = 1; + vel = 644; + + j = -1; + + if (p >= 0) + { + j = aim(s, 48); + if (j >= 0) + { + if (isRRRA() && atwith == RPG2) + { + if (sprite[j].picnum == HEN || sprite[j].picnum == HENSTAYPUT) + var90 = ps[screenpeek].i; + else + var90 = j; + } + int dal = ((sprite[j].xrepeat * tilesiz[sprite[j].picnum].y) << 1) + (8 << 8); + zvel = ((sprite[j].z - sz - dal) * vel) / ldist(&sprite[ps[p].i], &sprite[j]); + if (sprite[j].picnum != RECON) + sa = getangle(sprite[j].x - sx, sprite[j].y - sy); + } + else zvel = -mulscale16(ps[p].horizon.sum().asq16(), 81); + if (atwith == RPG) + S_PlayActorSound(RPG_SHOOT, i); + else if (isRRRA()) + { + if (atwith == RPG2) + S_PlayActorSound(244, i); + else if (atwith == RRTILE1790) + S_PlayActorSound(94, i); + } + + } + else + { + int x; + j = findplayer(s, &x); + sa = getangle(ps[j].oposx - sx, ps[j].oposy - sy); + if (s->picnum == BOSS3) + sz -= (32 << 8); + else if (s->picnum == BOSS2) + { + vel += 128; + sz += 24 << 8; + } + + l = ldist(&sprite[ps[j].i], s); + zvel = ((ps[j].oposz - sz) * vel) / l; + + if (badguy(s) && (s->hitag & face_player_smart)) + sa = s->ang + (krand() & 31) - 16; + } + + if (p >= 0 && j >= 0) + l = j; + else l = -1; + + if (isRRRA() && atwith == RRTILE1790) + { + zvel = -(10 << 8); + vel <<= 1; + } + + j = EGS(sect, + sx + (sintable[(348 + sa + 512) & 2047] / 448), + sy + (sintable[(sa + 348) & 2047] / 448), + sz - (1 << 8), atwith, 0, 14, 14, sa, vel, zvel, i, 4); + + if (isRRRA()) + { + if (atwith == RRTILE1790) + { + sprite[j].extra = 10; + sprite[j].zvel = -(10 << 8); + } + else if (atwith == RPG2) + { + sprite[j].lotag = var90; + sprite[j].hitag = 0; + fi.lotsofmoney(&sprite[j], (krand() & 3) + 1); + } + } + + sprite[j].extra += (krand() & 7); + if (atwith != FREEZEBLAST) + sprite[j].yvel = l; + else + { + sprite[j].yvel = numfreezebounces; + sprite[j].xrepeat >>= 1; + sprite[j].yrepeat >>= 1; + sprite[j].zvel -= (2 << 4); + } + + if (p == -1) + { + if (s->picnum == HULK) + { + sprite[j].xrepeat = 8; + sprite[j].yrepeat = 8; + } + else if (atwith != FREEZEBLAST) + { + sprite[j].xrepeat = 30; + sprite[j].yrepeat = 30; + sprite[j].extra >>= 2; + } + } + else if (ps[p].curr_weapon == TIT_WEAPON) + { + sprite[j].extra >>= 2; + sprite[j].ang += 16 - (krand() & 31); + sprite[j].zvel += 256 - (krand() & 511); + + if (ps[p].hbomb_hold_delay) + { + sprite[j].x -= sintable[sa & 2047] / 644; + sprite[j].y -= sintable[(sa + 1024 + 512) & 2047] / 644; + } + else + { + sprite[j].x += sintable[sa & 2047] >> 8; + sprite[j].y += sintable[(sa + 1024 + 512) & 2047] >> 8; + } + sprite[j].xrepeat >>= 1; + sprite[j].yrepeat >>= 1; + } + + sprite[j].cstat = 128; + if (atwith == RPG || (atwith == RPG2 && isRRRA())) + sprite[j].clipdist = 4; + else + sprite[j].clipdist = 40; + + +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void shootwhip(int i, int p, int sx, int sy, int sz, int sa, int atwith) +{ + spritetype* const s = &sprite[i]; + int sect = s->sectnum; + int vel, zvel; + short l, j, scount; + + if (s->extra >= 0) s->shade = -96; + + scount = 1; + if (atwith == 3471) + { + vel = 300; + sz -= (15 << 8); + scount = 1; + } + else if (atwith == 3475) + { + vel = 300; + sz += (4 << 8); + scount = 1; + } + + if (p >= 0) + { + j = aim(s, AUTO_AIM_ANGLE); + + if (j >= 0) + { + int dal = ((sprite[j].xrepeat * tilesiz[sprite[j].picnum].y) << 1) - (12 << 8); + zvel = ((sprite[j].z - sz - dal) * vel) / ldist(&sprite[ps[p].i], &sprite[j]); + sa = getangle(sprite[j].x - sx, sprite[j].y - sy); + } + else + zvel = -mulscale16(ps[p].horizon.sum().asq16(), 98); + } + else + { + int x; + j = findplayer(s, &x); + // sa = getangle(ps[j].oposx-sx,ps[j].oposy-sy); + if (s->picnum == VIXEN) + sa -= (krand() & 16); + else + sa += 16 - (krand() & 31); + zvel = (((ps[j].oposz - sz + (3 << 8))) * vel) / ldist(&sprite[ps[j].i], s); + } + + int oldzvel = zvel; + int sizx = 18; + int sizy = 18; + + if (p >= 0) sizx = 7, sizy = 7; + else sizx = 8, sizy = 8; + + while (scount > 0) + { + j = EGS(sect, sx, sy, sz, atwith, -127, sizx, sizy, sa, vel, zvel, i, 4); + sprite[j].extra += (krand() & 7); + + sprite[j].cstat = 128; + sprite[j].clipdist = 4; + + sa = s->ang + 32 - (krand() & 63); + zvel = oldzvel + 512 - (krand() & 1023); + + scount--; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + void shoot_r(int i, int atwith) { short sect, hitsect, hitspr, hitwall, l, sa, p, j, k, scount; @@ -134,425 +882,24 @@ void shoot_r(int i, int atwith) switch (atwith) { - case SLINGBLADE: - if (!isRRRA()) break; - goto rrra_slingblade; - case BLOODSPLAT1: case BLOODSPLAT2: case BLOODSPLAT3: case BLOODSPLAT4: + shootbloodsplat(i, p, sx, sy, sz, sa, atwith, BIGFORCE, OOZFILTER, -1); + return; - if (p >= 0) - sa += 64 - (krand() & 127); - else sa += 1024 + 64 - (krand() & 127); - zvel = 1024 - (krand() & 2047); + case SLINGBLADE: + if (!isRRRA()) break; case KNEE: case GROWSPARK: - rrra_slingblade: - if (atwith == KNEE || atwith == GROWSPARK || atwith == SLINGBLADE) - { - if (p >= 0) - { - zvel = -ps[p].horizon.sum().asq16() >> 11; - sz += (6 << 8); - sa += 15; - } - else - { - j = ps[findplayer(s, &x)].i; - zvel = ((sprite[j].z - sz) << 8) / (x + 1); - sa = getangle(sprite[j].x - sx, sprite[j].y - sy); - } - } - - hitscan(sx, sy, sz, sect, - sintable[(sa + 512) & 2047], - sintable[sa & 2047], zvel << 6, - &hitsect, &hitwall, &hitspr, &hitx, &hity, &hitz, CLIPMASK1); - - if (isRRRA() && ((sector[hitsect].lotag == 160 && zvel > 0) || (sector[hitsect].lotag == 161 && zvel < 0)) - && hitspr == -1 && hitwall == -1) - { - short ii; - for (ii = 0; ii < MAXSPRITES; ii++) - { - if (sprite[ii].sectnum == hitsect && sprite[ii].picnum == SECTOREFFECTOR - && sprite[ii].lotag == 7) - { - int nx, ny, nz; - nx = hitx + (sprite[sprite[ii].owner].x - sprite[ii].x); - ny = hity + (sprite[sprite[ii].owner].y - sprite[ii].y); - if (sector[hitsect].lotag == 161) - { - nz = sector[sprite[sprite[ii].owner].sectnum].floorz; - } - else - { - nz = sector[sprite[sprite[ii].owner].sectnum].ceilingz; - } - hitscan(nx, ny, nz, sprite[sprite[ii].owner].sectnum, - sintable[(sa + 512) & 2047], - sintable[sa & 2047], zvel << 6, - &hitsect, &hitwall, &hitspr, &hitx, &hity, &hitz, CLIPMASK1); - break; - } - } - } - - if (atwith == BLOODSPLAT1 || - atwith == BLOODSPLAT2 || - atwith == BLOODSPLAT3 || - atwith == BLOODSPLAT4) - { - if (FindDistance2D(sx - hitx, sy - hity) < 1024) - if (hitwall >= 0 && wall[hitwall].overpicnum != BIGFORCE) - if ((wall[hitwall].nextsector >= 0 && hitsect >= 0 && - sector[wall[hitwall].nextsector].lotag == 0 && - sector[hitsect].lotag == 0 && - sector[wall[hitwall].nextsector].lotag == 0 && - (sector[hitsect].floorz - sector[wall[hitwall].nextsector].floorz) > (16 << 8)) || - (wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0)) - if ((wall[hitwall].cstat & 16) == 0) - { - if (wall[hitwall].nextsector >= 0) - { - SectIterator it(wall[hitwall].nextsector); - while ((k = it.NextIndex()) >= 0) - { - if (sprite[k].statnum == 3 && sprite[k].lotag == 13) - return; - } - } - - if (wall[hitwall].nextwall >= 0 && - wall[wall[hitwall].nextwall].hitag != 0) - return; - - if (wall[hitwall].hitag == 0) - { - k = fi.spawn(i, atwith); - sprite[k].xvel = -12; - sprite[k].ang = getangle(wall[hitwall].x - wall[wall[hitwall].point2].x, - wall[hitwall].y - wall[wall[hitwall].point2].y) + 512; - sprite[k].x = hitx; - sprite[k].y = hity; - sprite[k].z = hitz; - sprite[k].cstat |= (krand() & 4); - ssp(k, CLIPMASK0); - setsprite(k, sprite[k].x, sprite[k].y, sprite[k].z); - if (s->picnum == OOZFILTER) - sprite[k].pal = 6; - } - } - return; - } - - if (hitsect < 0) break; - - if ((abs(sx - hitx) + abs(sy - hity)) < 1024) - { - if (hitwall >= 0 || hitspr >= 0) - { - if (isRRRA() && atwith == SLINGBLADE) - { - j = EGS(hitsect, hitx, hity, hitz, SLINGBLADE, -15, 0, 0, sa, 32, 0, i, 4); - sprite[j].extra += 50; - } - else - { - j = EGS(hitsect, hitx, hity, hitz, KNEE, -15, 0, 0, sa, 32, 0, i, 4); - sprite[j].extra += (krand() & 7); - } - if (p >= 0) - { - k = fi.spawn(j, SMALLSMOKE); - sprite[k].z -= (8 << 8); - if (atwith == KNEE) - S_PlayActorSound(KICK_HIT, j); - else if (isRRRA() && atwith == SLINGBLADE) - S_PlayActorSound(260, j); - } - - if (p >= 0 && ps[p].steroids_amount > 0 && ps[p].steroids_amount < 400) - sprite[j].extra += (max_player_health >> 2); - - if (hitspr >= 0 && sprite[hitspr].picnum != ACCESSSWITCH && sprite[hitspr].picnum != ACCESSSWITCH2) - { - fi.checkhitsprite(hitspr, j); - if (p >= 0) fi.checkhitswitch(p, hitspr, 1); - } - else if (hitwall >= 0) - { - if (wall[hitwall].cstat & 2) - if (wall[hitwall].nextsector >= 0) - if (hitz >= (sector[wall[hitwall].nextsector].floorz)) - hitwall = wall[hitwall].nextwall; - - if (hitwall >= 0 && wall[hitwall].picnum != ACCESSSWITCH && wall[hitwall].picnum != ACCESSSWITCH2) - { - fi.checkhitwall(j, hitwall, hitx, hity, hitz, atwith); - if (p >= 0) fi.checkhitswitch(p, hitwall, 0); - } - } - } - else if (p >= 0 && zvel > 0 && sector[hitsect].lotag == 1) - { - j = fi.spawn(ps[p].i, WATERSPLASH2); - sprite[j].x = hitx; - sprite[j].y = hity; - sprite[j].ang = ps[p].angle.ang.asbuild(); // Total tweek - sprite[j].xvel = 32; - ssp(i, 0); - sprite[j].xvel = 0; - - } - } - - break; + shootmelee(i, p, sx, sy, sz, sa, atwith); + return; case SHOTSPARK1: case SHOTGUN: case CHAINGUN: - - if (s->extra >= 0) s->shade = -96; - - if (p >= 0) - { - j = aim(s, AUTO_AIM_ANGLE); - if (j >= 0) - { - dal = ((sprite[j].xrepeat * tilesiz[sprite[j].picnum].y) << 1) + (5 << 8); - zvel = ((sprite[j].z - sz - dal) << 8) / ldist(&sprite[ps[p].i], &sprite[j]); - sa = getangle(sprite[j].x - sx, sprite[j].y - sy); - } - - if (atwith == SHOTSPARK1) - { - if (j == -1) - { - sa += 16 - (krand() & 31); - zvel = -ps[p].horizon.sum().asq16() >> 11; - zvel += 128 - (krand() & 255); - } - } - else - { - if (atwith == SHOTGUN) - sa += 64 - (krand() & 127); - else - sa += 16 - (krand() & 31); - if (j == -1) zvel = -ps[p].horizon.sum().asq16() >> 11; - zvel += 128 - (krand() & 255); - } - sz -= (2 << 8); - } - else - { - j = findplayer(s, &x); - sz -= (4 << 8); - zvel = ((ps[j].posz - sz) << 8) / (ldist(&sprite[ps[j].i], s)); - if (s->picnum != BOSS1) - { - zvel += 128 - (krand() & 255); - sa += 32 - (krand() & 63); - } - else - { - zvel += 128 - (krand() & 255); - sa = getangle(ps[j].posx - sx, ps[j].posy - sy) + 64 - (krand() & 127); - } - } - - s->cstat &= ~257; - hitscan(sx, sy, sz, sect, - sintable[(sa + 512) & 2047], - sintable[sa & 2047], - zvel << 6, &hitsect, &hitwall, &hitspr, &hitx, &hity, &hitz, CLIPMASK1); - - if (isRRRA() && (((sector[hitsect].lotag == 160 && zvel > 0) || (sector[hitsect].lotag == 161 && zvel < 0)) - && hitspr == -1 && hitwall == -1)) - { - short ii; - for (ii = 0; ii < MAXSPRITES; ii++) - { - if (sprite[ii].sectnum == hitsect && sprite[ii].picnum == SECTOREFFECTOR - && sprite[ii].lotag == 7) - { - int nx, ny, nz; - nx = hitx + (sprite[sprite[ii].owner].x - sprite[ii].x); - ny = hity + (sprite[sprite[ii].owner].y - sprite[ii].y); - if (sector[hitsect].lotag == 161) - { - nz = sector[sprite[sprite[ii].owner].sectnum].floorz; - } - else - { - nz = sector[sprite[sprite[ii].owner].sectnum].ceilingz; - } - hitscan(nx, ny, nz, sprite[sprite[ii].owner].sectnum, - sintable[(sa + 512) & 2047], - sintable[sa & 2047], zvel << 6, - &hitsect, &hitwall, &hitspr, &hitx, &hity, &hitz, CLIPMASK1); - break; - } - } - } - - s->cstat |= 257; - - if (hitsect < 0) return; - - if (atwith == SHOTGUN) - if (sector[hitsect].lotag == 1) - if (krand() & 1) - return; - - if ((krand() & 15) == 0 && sector[hitsect].lotag == 2) - tracers(hitx, hity, hitz, sx, sy, sz, 8 - (ud.multimode >> 1)); - - if (p >= 0) - { - k = EGS(hitsect, hitx, hity, hitz, SHOTSPARK1, -15, 10, 10, sa, 0, 0, i, 4); - sprite[k].extra = ScriptCode[actorinfo[atwith].scriptaddress]; - sprite[k].extra += (krand() % 6); - - if (hitwall == -1 && hitspr == -1) - { - if (zvel < 0) - { - if (sector[hitsect].ceilingstat & 1) - { - sprite[k].xrepeat = 0; - sprite[k].yrepeat = 0; - return; - } - else - fi.checkhitceiling(hitsect); - } - if (sector[hitsect].lotag != 1) - fi.spawn(k, SMALLSMOKE); - } - - if (hitspr >= 0) - { - if (sprite[hitspr].picnum == 1930) - return; - fi.checkhitsprite(hitspr, k); - if (sprite[hitspr].picnum == TILE_APLAYER && (ud.coop != 1 || ud.ffire == 1)) - { - l = fi.spawn(k, JIBS6); - sprite[k].xrepeat = sprite[k].yrepeat = 0; - sprite[l].z += (4 << 8); - sprite[l].xvel = 16; - sprite[l].xrepeat = sprite[l].yrepeat = 24; - sprite[l].ang += 64 - (krand() & 127); - } - else fi.spawn(k, SMALLSMOKE); - - if (p >= 0 && ( - sprite[hitspr].picnum == DIPSWITCH || - sprite[hitspr].picnum == DIPSWITCH + 1 || - sprite[hitspr].picnum == DIPSWITCH2 || - sprite[hitspr].picnum == DIPSWITCH2 + 1 || - sprite[hitspr].picnum == DIPSWITCH3 || - sprite[hitspr].picnum == DIPSWITCH3 + 1 || - (isRRRA() && sprite[hitspr].picnum == RRTILE8660) || - sprite[hitspr].picnum == HANDSWITCH || - sprite[hitspr].picnum == HANDSWITCH + 1)) - { - fi.checkhitswitch(p, hitspr, 1); - return; - } - } - else if (hitwall >= 0) - { - fi.spawn(k, SMALLSMOKE); - - if (fi.isadoorwall(wall[hitwall].picnum) == 1) - goto SKIPBULLETHOLE; - if (isablockdoor(wall[hitwall].picnum) == 1) - goto SKIPBULLETHOLE; - if (p >= 0 && ( - wall[hitwall].picnum == DIPSWITCH || - wall[hitwall].picnum == DIPSWITCH + 1 || - wall[hitwall].picnum == DIPSWITCH2 || - wall[hitwall].picnum == DIPSWITCH2 + 1 || - wall[hitwall].picnum == DIPSWITCH3 || - wall[hitwall].picnum == DIPSWITCH3 + 1 || - (isRRRA() && wall[hitwall].picnum == RRTILE8660) || - wall[hitwall].picnum == HANDSWITCH || - wall[hitwall].picnum == HANDSWITCH + 1)) - { - fi.checkhitswitch(p, hitwall, 0); - return; - } - - if (wall[hitwall].hitag != 0 || (wall[hitwall].nextwall >= 0 && wall[wall[hitwall].nextwall].hitag != 0)) - goto SKIPBULLETHOLE; - - if (hitsect >= 0 && sector[hitsect].lotag == 0) - if (wall[hitwall].overpicnum != BIGFORCE) - if ((wall[hitwall].nextsector >= 0 && sector[wall[hitwall].nextsector].lotag == 0) || - (wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0)) - if ((wall[hitwall].cstat & 16) == 0) - { - if (wall[hitwall].nextsector >= 0) - { - SectIterator it(wall[hitwall].nextsector); - while ((l = it.NextIndex()) >= 0) - { - if (sprite[l].statnum == 3 && sprite[l].lotag == 13) - goto SKIPBULLETHOLE; - } - } - - StatIterator it(STAT_MISC); - while ((l = it.NextIndex()) >= 0) - { - if (sprite[l].picnum == BULLETHOLE) - if (dist(&sprite[l], &sprite[k]) < (12 + (krand() & 7))) - goto SKIPBULLETHOLE; - } - l = fi.spawn(k, BULLETHOLE); - sprite[l].xvel = -1; - sprite[l].ang = getangle(wall[hitwall].x - wall[wall[hitwall].point2].x, - wall[hitwall].y - wall[wall[hitwall].point2].y) + 512; - ssp(l, CLIPMASK0); - } - - SKIPBULLETHOLE: - - if (wall[hitwall].cstat & 2) - if (wall[hitwall].nextsector >= 0) - if (hitz >= (sector[wall[hitwall].nextsector].floorz)) - hitwall = wall[hitwall].nextwall; - - fi.checkhitwall(k, hitwall, hitx, hity, hitz, SHOTSPARK1); - } - } - else - { - k = EGS(hitsect, hitx, hity, hitz, SHOTSPARK1, -15, 24, 24, sa, 0, 0, i, 4); - sprite[k].extra = ScriptCode[actorinfo[atwith].scriptaddress]; - - if (hitspr >= 0) - { - fi.checkhitsprite(hitspr, k); - if (sprite[hitspr].picnum != TILE_APLAYER) - fi.spawn(k, SMALLSMOKE); - else sprite[k].xrepeat = sprite[k].yrepeat = 0; - } - else if (hitwall >= 0) - fi.checkhitwall(k, hitwall, hitx, hity, hitz, SHOTSPARK1); - } - - if ((krand() & 255) < 10) - { - vec3_t v{ hitx, hity, hitz }; - S_PlaySound3D(PISTOL_RICOCHET, k, &v); - } - + shootweapon(i, p, sx, sy, sz, sa, atwith); return; case TRIPBOMBSPRITE: @@ -571,198 +918,13 @@ void shoot_r(int i, int atwith) case OWHIP: case UWHIP: - - if (s->extra >= 0) s->shade = -96; - - scount = 1; - if (atwith == 3471) - { - vel = 300; - sz -= (15 << 8); - scount = 1; - } - else if (atwith == 3475) - { - vel = 300; - sz += (4 << 8); - scount = 1; - } - - if (p >= 0) - { - j = aim(s, AUTO_AIM_ANGLE); - - if (j >= 0) - { - dal = ((sprite[j].xrepeat * tilesiz[sprite[j].picnum].y) << 1) - (12 << 8); - zvel = ((sprite[j].z - sz - dal) * vel) / ldist(&sprite[ps[p].i], &sprite[j]); - sa = getangle(sprite[j].x - sx, sprite[j].y - sy); - } - else - zvel = -mulscale16(ps[p].horizon.sum().asq16(), 98); - } - else - { - j = findplayer(s, &x); - // sa = getangle(ps[j].oposx-sx,ps[j].oposy-sy); - if (s->picnum == VIXEN) - sa -= (krand() & 16); - else - sa += 16 - (krand() & 31); - zvel = (((ps[j].oposz - sz + (3 << 8))) * vel) / ldist(&sprite[ps[j].i], s); - } - - oldzvel = zvel; - sizx = 18; sizy = 18; - - if (p >= 0) sizx = 7, sizy = 7; - else sizx = 8, sizy = 8; - - while (scount > 0) - { - j = EGS(sect, sx, sy, sz, atwith, -127, sizx, sizy, sa, vel, zvel, i, 4); - sprite[j].extra += (krand() & 7); - - sprite[j].cstat = 128; - sprite[j].clipdist = 4; - - sa = s->ang + 32 - (krand() & 63); - zvel = oldzvel + 512 - (krand() & 1023); - - scount--; - } - + shootwhip(i, p, sx, sy, sz, sa, atwith); return; case FIRELASER: case SPIT: case COOLEXPLOSION1: - - if (isRRRA()) - { - if (atwith != SPIT && s->extra >= 0) s->shade = -96; - - scount = 1; - if (atwith == SPIT) - { - if (s->picnum == 8705) - vel = 600; - else - vel = 400; - } - } - else - { - if (s->extra >= 0) s->shade = -96; - - scount = 1; - if (atwith == SPIT) vel = 400; - } - if (atwith != SPIT) - { - vel = 840; - sz -= (4 << 7); - if (s->picnum == 4649) - { - sx += sintable[(s->ang + 512 + 256) & 2047] >> 6; - sy += sintable[(s->ang + 256) & 2047] >> 6; - sz += (12 << 8); - } - if (s->picnum == VIXEN) - { - sz -= (12 << 8); - } - } - - if (p >= 0) - { - j = aim(s, AUTO_AIM_ANGLE); - - if (j >= 0) - { - sx += sintable[(s->ang + 512 + 160) & 2047] >> 7; - sy += sintable[(s->ang + 160) & 2047] >> 7; - dal = ((sprite[j].xrepeat * tilesiz[sprite[j].picnum].y) << 1) - (12 << 8); - zvel = ((sprite[j].z - sz - dal) * vel) / ldist(&sprite[ps[p].i], &sprite[j]); - sa = getangle(sprite[j].x - sx, sprite[j].y - sy); - } - else - { - sx += sintable[(s->ang + 512 + 160) & 2047] >> 7; - sy += sintable[(s->ang + 160) & 2047] >> 7; - zvel = -mulscale16(ps[p].horizon.sum().asq16(), 98); - } - } - else - { - j = findplayer(s, &x); - // sa = getangle(ps[j].oposx-sx,ps[j].oposy-sy); - if (s->picnum == HULK) - sa -= (krand() & 31); - else if (s->picnum == VIXEN) - sa -= (krand() & 16); - else if (s->picnum != UFOBEAM) - sa += 16 - (krand() & 31); - - zvel = (((ps[j].oposz - sz + (3 << 8))) * vel) / ldist(&sprite[ps[j].i], s); - } - - oldzvel = zvel; - - if (atwith == SPIT) - { - sizx = 18; sizy = 18; - if (!isRRRA() || s->picnum != MAMA) sz -= (10 << 8); else sz -= (20 << 8); - } - else - { - if (atwith == COOLEXPLOSION1) - { - sizx = 8; - sizy = 8; - } - else if (atwith == FIRELASER) - { - if (p >= 0) - { - - sizx = 34; - sizy = 34; - } - else - { - sizx = 18; - sizy = 18; - } - } - else - { - sizx = 18; - sizy = 18; - } - } - - if (p >= 0) sizx = 7, sizy = 7; - - while (scount > 0) - { - j = EGS(sect, sx, sy, sz, atwith, -127, sizx, sizy, sa, vel, zvel, i, 4); - sprite[j].extra += (krand() & 7); - sprite[j].cstat = 128; - sprite[j].clipdist = 4; - - sa = s->ang + 32 - (krand() & 63); - zvel = oldzvel + 512 - (krand() & 1023); - - if (atwith == FIRELASER) - { - sprite[j].xrepeat = 8; - sprite[j].yrepeat = 8; - } - - scount--; - } - + shootstuff(i, p, sx, sy, sz, sa, atwith); return; case RPG2: @@ -775,146 +937,8 @@ void shoot_r(int i, int atwith) case RPG: case SHRINKSPARK: rrra_rpg2: - { - short var90 = 0; - if (s->extra >= 0) s->shade = -96; - - scount = 1; - vel = 644; - - j = -1; - - if (p >= 0) - { - j = aim(s, 48); - if (j >= 0) - { - if (isRRRA() && atwith == RPG2) - { - if (sprite[j].picnum == HEN || sprite[j].picnum == HENSTAYPUT) - var90 = ps[screenpeek].i; - else - var90 = j; - } - dal = ((sprite[j].xrepeat * tilesiz[sprite[j].picnum].y) << 1) + (8 << 8); - zvel = ((sprite[j].z - sz - dal) * vel) / ldist(&sprite[ps[p].i], &sprite[j]); - if (sprite[j].picnum != RECON) - sa = getangle(sprite[j].x - sx, sprite[j].y - sy); - } - else zvel = -mulscale16(ps[p].horizon.sum().asq16(), 81); - if (atwith == RPG) - S_PlayActorSound(RPG_SHOOT, i); - else if (isRRRA()) - { - if (atwith == RPG2) - S_PlayActorSound(244, i); - else if (atwith == RRTILE1790) - S_PlayActorSound(94, i); - } - - } - else - { - j = findplayer(s, &x); - sa = getangle(ps[j].oposx - sx, ps[j].oposy - sy); - if (s->picnum == BOSS3) - sz -= (32 << 8); - else if (s->picnum == BOSS2) - { - vel += 128; - sz += 24 << 8; - } - - l = ldist(&sprite[ps[j].i], s); - zvel = ((ps[j].oposz - sz) * vel) / l; - - if (badguy(s) && (s->hitag & face_player_smart)) - sa = s->ang + (krand() & 31) - 16; - } - - if (p >= 0 && j >= 0) - l = j; - else l = -1; - - if (isRRRA() && atwith == RRTILE1790) - { - zvel = -(10 << 8); - vel <<= 1; - } - - j = EGS(sect, - sx + (sintable[(348 + sa + 512) & 2047] / 448), - sy + (sintable[(sa + 348) & 2047] / 448), - sz - (1 << 8), atwith, 0, 14, 14, sa, vel, zvel, i, 4); - - if (isRRRA()) - { - if (atwith == RRTILE1790) - { - sprite[j].extra = 10; - sprite[j].zvel = -(10 << 8); - } - else if (atwith == RPG2) - { - sprite[j].lotag = var90; - sprite[j].hitag = 0; - fi.lotsofmoney(&sprite[j], (krand() & 3) + 1); - } - } - - sprite[j].extra += (krand() & 7); - if (atwith != FREEZEBLAST) - sprite[j].yvel = l; - else - { - sprite[j].yvel = numfreezebounces; - sprite[j].xrepeat >>= 1; - sprite[j].yrepeat >>= 1; - sprite[j].zvel -= (2 << 4); - } - - if (p == -1) - { - if (s->picnum == HULK) - { - sprite[j].xrepeat = 8; - sprite[j].yrepeat = 8; - } - else if (atwith != FREEZEBLAST) - { - sprite[j].xrepeat = 30; - sprite[j].yrepeat = 30; - sprite[j].extra >>= 2; - } - } - else if (ps[p].curr_weapon == TIT_WEAPON) - { - sprite[j].extra >>= 2; - sprite[j].ang += 16 - (krand() & 31); - sprite[j].zvel += 256 - (krand() & 511); - - if (ps[p].hbomb_hold_delay) - { - sprite[j].x -= sintable[sa & 2047] / 644; - sprite[j].y -= sintable[(sa + 1024 + 512) & 2047] / 644; - } - else - { - sprite[j].x += sintable[sa & 2047] >> 8; - sprite[j].y += sintable[(sa + 1024 + 512) & 2047] >> 8; - } - sprite[j].xrepeat >>= 1; - sprite[j].yrepeat >>= 1; - } - - sprite[j].cstat = 128; - if (atwith == RPG || (atwith == RPG2 && isRRRA())) - sprite[j].clipdist = 4; - else - sprite[j].clipdist = 40; - - } - break; + shootrpg(i, p, sx, sy, sz, sa, atwith); + break; case CHEERBOMB: if (!isRRRA()) break;