diff --git a/source/build/include/clip.h b/source/build/include/clip.h index 707bdb261..e4a231698 100644 --- a/source/build/include/clip.h +++ b/source/build/include/clip.h @@ -71,6 +71,11 @@ typedef struct extern int16_t clipsectorlist[MAXCLIPSECTORS]; int clipinsidebox(vec2_t *vect, int wallnum, int walldist); +inline int clipinsidebox(int x, int y, int wall, int dist) +{ + vec2_t v = { x, y }; + return clipinsidebox(&v, wall, dist); +} int clipinsideboxline(int x, int y, int x1, int y1, int x2, int y2, int walldist); extern int32_t clipmoveboxtracenum; diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 2622fcc0c..a546498c5 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -1527,7 +1527,7 @@ bool queball(int i, int pocket, int queball, int stripeball) int j, nextj; if (s->xvel) { - j = headspritestat[0]; + j = headspritestat[STAT_DEFAULT]; while (j >= 0) { nextj = nextspritestat[j]; @@ -1583,7 +1583,7 @@ bool queball(int i, int pocket, int queball, int stripeball) if (j > -64 && j < 64 && PlayerInput(p, SK_OPEN)) if (ps[p].toggle_key_flag == 1) { - int a = headspritestat[1]; + int a = headspritestat[STAT_ACTOR]; while (a >= 0) { if (sprite[a].picnum == queball || sprite[a].picnum == stripeball) @@ -1661,7 +1661,7 @@ void forcesphere(int i, int forcesphere) } else if (t[2] > 10) { - int j = headspritestat[5]; + int j = headspritestat[STAT_MISC]; while (j >= 0) { if (sprite[j].owner == i && sprite[j].picnum == forcesphere) @@ -1978,7 +1978,7 @@ void reactor(int i, int REACTOR, int REACTOR2, int REACTORBURNT, int REACTOR2BUR impact_damage << 2, impact_damage << 2, impact_damage << 2); - j = headspritestat[6]; + j = headspritestat[STAT_STANDABLE]; while (j >= 0) { if (sprite[j].picnum == MASTERSWITCH) @@ -2612,4 +2612,2119 @@ void scrap(int i, int SCRAP1, int SCRAP6) } } +//--------------------------------------------------------------------------- +// +// taken out of moveeffectors +// +//--------------------------------------------------------------------------- + +void handle_se00(int i, int LASERLINE) +{ + spritetype* s = &sprite[i]; + int sect = s->sectnum; + auto t = &hittype[i].temp_data[0]; + sectortype *sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + + int zchange = 0; + + int j = s->owner; + + if (sprite[j].lotag == (short)65535) + { + deletesprite(i); + return; + } + + int q = sc->extra >> 3; + int l = 0; + + if (sc->lotag == 30) + { + q >>= 2; + + if (sprite[i].extra == 1) + { + if (hittype[i].tempang < 256) + { + hittype[i].tempang += 4; + if (hittype[i].tempang >= 256) + callsound(s->sectnum, i); + if (s->clipdist) l = 1; + else l = -1; + } + else hittype[i].tempang = 256; + + if (sc->floorz > s->z) //z's are touching + { + sc->floorz -= 512; + zchange = -512; + if (sc->floorz < s->z) + sc->floorz = s->z; + } + + else if (sc->floorz < s->z) //z's are touching + { + sc->floorz += 512; + zchange = 512; + if (sc->floorz > s->z) + sc->floorz = s->z; + } + } + else if (sprite[i].extra == 3) + { + if (hittype[i].tempang > 0) + { + hittype[i].tempang -= 4; + if (hittype[i].tempang <= 0) + callsound(s->sectnum, i); + if (s->clipdist) l = -1; + else l = 1; + } + else hittype[i].tempang = 0; + + if (sc->floorz > hittype[i].temp_data[3]) //z's are touching + { + sc->floorz -= 512; + zchange = -512; + if (sc->floorz < hittype[i].temp_data[3]) + sc->floorz = hittype[i].temp_data[3]; + } + + else if (sc->floorz < hittype[i].temp_data[3]) //z's are touching + { + sc->floorz += 512; + zchange = 512; + if (sc->floorz > hittype[i].temp_data[3]) + sc->floorz = hittype[i].temp_data[3]; + } + } + + s->ang += (l * q); + t[2] += (l * q); + } + else + { + if (hittype[j].temp_data[0] == 0) return; + if (hittype[j].temp_data[0] == 2) + { + deletesprite(i); + return; + } + + if (sprite[j].ang > 1024) + l = -1; + else l = 1; + if (t[3] == 0) + t[3] = ldist(s, &sprite[j]); + s->xvel = t[3]; + s->x = sprite[j].x; + s->y = sprite[j].y; + s->ang += (l * q); + t[2] += (l * q); + } + + if (l && (sc->floorstat & 64)) + { + int p; + for (p = connecthead; p >= 0; p = connectpoint2[p]) + { + if (ps[p].cursectnum == s->sectnum && ps[p].on_ground == 1) + { + + ps[p].addang(l * q); + + ps[p].posz += zchange; + + int m, x; + rotatepoint(sprite[j].x, sprite[j].y, + ps[p].posx, ps[p].posy, (q * l), + &m, &x); + + ps[p].bobposx += m - ps[p].posx; + ps[p].bobposy += x - ps[p].posy; + + ps[p].posx = m; + ps[p].posy = x; + + if (sprite[ps[p].i].extra <= 0) + { + sprite[ps[p].i].x = m; + sprite[ps[p].i].y = x; + } + } + } + + p = headspritesect[s->sectnum]; + while (p >= 0) + { + if (sprite[p].statnum != 3 && sprite[p].statnum != 4) + if (LASERLINE < 0 || sprite[p].picnum != LASERLINE) + { + if (sprite[p].picnum == APLAYER && sprite[p].owner >= 0) + { + p = nextspritesect[p]; + continue; + } + + sprite[p].ang += (l * q); + sprite[p].ang &= 2047; + + sprite[p].z += zchange; + + rotatepoint(sprite[j].x, sprite[j].y, + sprite[p].x, sprite[p].y, (q * l), + &sprite[p].x, &sprite[p].y); + + } + p = nextspritesect[p]; + } + + } + ms(i); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se01(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + int sh = s->hitag; + if (s->owner == -1) //Init + { + s->owner = i; + + int j = headspritestat[STAT_EFFECTOR]; + while (j >= 0) + { + if (sprite[j].lotag == 19 && sprite[j].hitag == sh) + { + t[0] = 0; + break; + } + j = nextspritestat[j]; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se14(int i, bool checkstat, int RPG, int JIBS6) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + + if (s->owner == -1) + s->owner = LocateTheLocator(t[3], t[0]); + + if (s->owner == -1) + { + I_Error("Could not find any locators for SE# 6 and 14 with a hitag of %ld.", t[3]); + } + + int j = ldist(&sprite[s->owner], s); + + if (j < 1024L) + { + if (st == 6) + if (sprite[s->owner].hitag & 1) + t[4] = sc->extra; //Slow it down + t[3]++; + s->owner = LocateTheLocator(t[3], t[0]); + if (s->owner == -1) + { + t[3] = 0; + s->owner = LocateTheLocator(0, t[0]); + } + } + + if (s->xvel) + { + int x = getangle(sprite[s->owner].x - s->x, sprite[s->owner].y - s->y); + int q = getincangle(s->ang, x) >> 3; + + t[2] += q; + s->ang += q; + + bool statstate = (!checkstat || ((sc->floorstat & 1) == 0 && (sc->ceilingstat & 1) == 0)); + if (s->xvel == sc->extra) + { + if (statstate) + { + if (!S_CheckSoundPlaying(hittype[i].lastvx) == 0) + spritesound(hittype[i].lastvx, i); + } + if ((!checkstat || !statstate) && (ud.monsters_off == 0 && sc->floorpal == 0 && (sc->floorstat & 1) && rnd(8))) + { + int p = findplayer(s, &x); + if (x < 20480) + { + j = s->ang; + s->ang = getangle(s->x - ps[p].posx, s->y - ps[p].posy); + shoot(i, RPG); + s->ang = j; + } + } + } + + if (s->xvel <= 64 && statstate) + stopsound(hittype[i].lastvx); + + if ((sc->floorz - sc->ceilingz) < (108 << 8)) + { + if (ud.clipping == 0 && s->xvel >= 192) + for (int p = connecthead; p >= 0; p = connectpoint2[p]) + if (sprite[ps[p].i].extra > 0) + { + short k = ps[p].cursectnum; + updatesector(ps[p].posx, ps[p].posy, &k); + if ((k == -1 && ud.clipping == 0) || (k == s->sectnum && ps[p].cursectnum != s->sectnum)) + { + ps[p].posx = s->x; + ps[p].posy = s->y; + ps[p].cursectnum = s->sectnum; + + setsprite(ps[p].i, s->x, s->y, s->z); + quickkill(&ps[p]); + } + } + } + + int m = (s->xvel * sintable[(s->ang + 512) & 2047]) >> 14; + x = (s->xvel * sintable[s->ang & 2047]) >> 14; + + for (int p = connecthead; p >= 0; p = connectpoint2[p]) + if (sector[ps[p].cursectnum].lotag != 2) + { + if (po[p].os == s->sectnum) + { + po[p].ox += m; + po[p].oy += x; + } + + if (s->sectnum == sprite[ps[p].i].sectnum) + { + rotatepoint(s->x, s->y, ps[p].posx, ps[p].posy, q, &ps[p].posx, &ps[p].posy); + + ps[p].posx += m; + ps[p].posy += x; + + ps[p].bobposx += m; + ps[p].bobposy += x; + + ps[p].addang(q); + + if (numplayers > 1) + { + ps[p].oposx = ps[p].posx; + ps[p].oposy = ps[p].posy; + } + if (sprite[ps[p].i].extra <= 0) + { + sprite[ps[p].i].x = ps[p].posx; + sprite[ps[p].i].y = ps[p].posy; + } + } + } + j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].statnum != 10 && sector[sprite[j].sectnum].lotag != 2 && sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS) + { + rotatepoint(s->x, s->y, + sprite[j].x, sprite[j].y, q, + &sprite[j].x, &sprite[j].y); + + sprite[j].x += m; + sprite[j].y += x; + + sprite[j].ang += q; + + if (numplayers > 1) + { + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + } + } + j = nextspritesect[j]; + } + + ms(i); + setsprite(i, s->x, s->y, s->z); + + if ((sc->floorz - sc->ceilingz) < (108 << 8)) + { + if (ud.clipping == 0 && s->xvel >= 192) + for (int p = connecthead; p >= 0; p = connectpoint2[p]) + if (sprite[ps[p].i].extra > 0) + { + short k = ps[p].cursectnum; + updatesector(ps[p].posx, ps[p].posy, &k); + if ((k == -1 && ud.clipping == 0) || (k == s->sectnum && ps[p].cursectnum != s->sectnum)) + { + ps[p].oposx = ps[p].posx = s->x; + ps[p].oposy = ps[p].posy = s->y; + ps[p].cursectnum = s->sectnum; + + setsprite(ps[p].i, s->x, s->y, s->z); + quickkill(&ps[p]); + } + } + + j = headspritesect[sprite[sprite[i].owner].sectnum]; + while (j >= 0) + { + int l = nextspritesect[j]; + if (sprite[j].statnum == 1 && badguy(&sprite[j]) && sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS) + { + short k = sprite[j].sectnum; + updatesector(sprite[j].x, sprite[j].y, &k); + if (sprite[j].extra >= 0 && k == s->sectnum) + { + gutsdir(&sprite[j], JIBS6, 72, myconnectindex); + spritesound(SQUISHED, i); + deletesprite(j); + } + } + j = l; + } + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se30(int i, int JIBS6) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + + if (s->owner == -1) + { + t[3] = !t[3]; + s->owner = LocateTheLocator(t[3], t[0]); + } + else + { + + if (t[4] == 1) // Starting to go + { + if (ldist(&sprite[s->owner], s) < (2048 - 128)) + t[4] = 2; + else + { + if (s->xvel == 0) + operateactivators(s->hitag + (!t[3]), -1); + if (s->xvel < 256) + s->xvel += 16; + } + } + if (t[4] == 2) + { + int l = FindDistance2D(sprite[s->owner].x - s->x, sprite[s->owner].y - s->y); + + if (l <= 128) + s->xvel = 0; + + if (s->xvel > 0) + s->xvel -= 16; + else + { + s->xvel = 0; + operateactivators(s->hitag + (short)t[3], -1); + s->owner = -1; + s->ang += 1024; + t[4] = 0; + operateforcefields(i, s->hitag); + + int j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS) + { + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + } + j = nextspritesect[j]; + } + + } + } + } + + if (s->xvel) + { + int l = (s->xvel * sintable[(s->ang + 512) & 2047]) >> 14; + int x = (s->xvel * sintable[s->ang & 2047]) >> 14; + + if ((sc->floorz - sc->ceilingz) < (108 << 8)) + if (ud.clipping == 0) + for (int p = connecthead; p >= 0; p = connectpoint2[p]) + if (sprite[ps[p].i].extra > 0) + { + short k = ps[p].cursectnum; + updatesector(ps[p].posx, ps[p].posy, &k); + if ((k == -1 && ud.clipping == 0) || (k == s->sectnum && ps[p].cursectnum != s->sectnum)) + { + ps[p].posx = s->x; + ps[p].posy = s->y; + ps[p].cursectnum = s->sectnum; + + setsprite(ps[p].i, s->x, s->y, s->z); + quickkill(&ps[p]); + } + } + + for (int p = connecthead; p >= 0; p = connectpoint2[p]) + { + if (sprite[ps[p].i].sectnum == s->sectnum) + { + ps[p].posx += l; + ps[p].posy += x; + + if (numplayers > 1) + { + ps[p].oposx = ps[p].posx; + ps[p].oposy = ps[p].posy; + } + + ps[p].bobposx += l; + ps[p].bobposy += x; + } + + if (po[p].os == s->sectnum) + { + po[p].ox += l; + po[p].oy += x; + } + } + + int j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS) + { + if (numplayers < 2) + { + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + } + + sprite[j].x += l; + sprite[j].y += x; + + if (numplayers > 1) + { + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + } + } + j = nextspritesect[j]; + } + + ms(i); + setsprite(i, s->x, s->y, s->z); + + if ((sc->floorz - sc->ceilingz) < (108 << 8)) + { + if (ud.clipping == 0) + for (int p = connecthead; p >= 0; p = connectpoint2[p]) + if (sprite[ps[p].i].extra > 0) + { + short k = ps[p].cursectnum; + updatesector(ps[p].posx, ps[p].posy, &k); + if ((k == -1 && ud.clipping == 0) || (k == s->sectnum && ps[p].cursectnum != s->sectnum)) + { + ps[p].posx = s->x; + ps[p].posy = s->y; + + ps[p].oposx = ps[p].posx; + ps[p].oposy = ps[p].posy; + + ps[p].cursectnum = s->sectnum; + + setsprite(ps[p].i, s->x, s->y, s->z); + quickkill(&ps[p]); + } + } + + j = headspritesect[sprite[sprite[i].owner].sectnum]; + while (j >= 0) + { + l = nextspritesect[j]; + if (sprite[j].statnum == 1 && badguy(&sprite[j]) && sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS) + { + // if(sprite[j].sectnum != s->sectnum) + { + short k = sprite[j].sectnum; + updatesector(sprite[j].x, sprite[j].y, &k); + if (sprite[j].extra >= 0 && k == s->sectnum) + { + gutsdir_d(&sprite[j], JIBS6, 24, myconnectindex); + spritesound(SQUISHED, j); + deletesprite(j); + } + } + + } + j = l; + } + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se02(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + + if (t[4] > 0 && t[0] == 0) + { + if (t[4] < sh) + t[4]++; + else t[0] = 1; + } + + if (t[0] > 0) + { + t[0]++; + + s->xvel = 3; + + if (t[0] > 96) + { + t[0] = -1; //Stop the quake + t[4] = -1; + deletesprite(i); + return; + } + else + { + if ((t[0] & 31) == 8) + { + earthquaketime = 48; + spritesound(EARTHQUAKE, ps[screenpeek].i); + } + + if (abs(sc->floorheinum - t[5]) < 8) + sc->floorheinum = t[5]; + else sc->floorheinum += (sgn(t[5] - sc->floorheinum) << 4); + } + + int m = (s->xvel * sintable[(s->ang + 512) & 2047]) >> 14; + int x = (s->xvel * sintable[s->ang & 2047]) >> 14; + + + for (int p = connecthead; p >= 0; p = connectpoint2[p]) + if (ps[p].cursectnum == s->sectnum && ps[p].on_ground) + { + ps[p].posx += m; + ps[p].posy += x; + + ps[p].bobposx += m; + ps[p].bobposy += x; + } + + int j = headspritesect[s->sectnum]; + while (j >= 0) + { + int nextj = nextspritesect[j]; + + if (sprite[j].picnum != SECTOREFFECTOR) + { + sprite[j].x += m; + sprite[j].y += x; + setsprite(j, sprite[j].x, sprite[j].y, sprite[j].z); + } + j = nextj; + } + ms(i); + setsprite(i, s->x, s->y, s->z); + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se03(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + + if (t[4] == 0) return; + int x, p = findplayer(s, &x); + + // if(t[5] > 0) { t[5]--; break; } + + if ((global_random / (sh + 1) & 31) < 4 && !t[2]) + { + // t[5] = 4+(global_random&7); + sc->ceilingpal = s->owner >> 8; + sc->floorpal = s->owner & 0xff; + t[0] = s->shade + (global_random & 15); + } + else + { + // t[5] = 4+(global_random&3); + sc->ceilingpal = s->pal; + sc->floorpal = s->pal; + t[0] = t[3]; + } + + sc->ceilingshade = t[0]; + sc->floorshade = t[0]; + + auto wal = &wall[sc->wallptr]; + + for (x = sc->wallnum; x > 0; x--, wal++) + { + if (wal->hitag != 1) + { + wal->shade = t[0]; + if ((wal->cstat & 2) && wal->nextwall >= 0) + { + wall[wal->nextwall].shade = wal->shade; + } + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se04(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + int j; + + if ((global_random / (sh + 1) & 31) < 4) + { + t[1] = s->shade + (global_random & 15);//Got really bright + t[0] = s->shade + (global_random & 15); + sc->ceilingpal = s->owner >> 8; + sc->floorpal = s->owner & 0xff; + j = 1; + } + else + { + t[1] = t[2]; + t[0] = t[3]; + + sc->ceilingpal = s->pal; + sc->floorpal = s->pal; + + j = 0; + } + + sc->floorshade = t[1]; + sc->ceilingshade = t[1]; + + auto wal = &wall[sc->wallptr]; + + for (int x = sc->wallnum; x > 0; x--, wal++) + { + if (j) wal->pal = (s->owner & 0xff); + else wal->pal = s->pal; + + if (wal->hitag != 1) + { + wal->shade = t[0]; + if ((wal->cstat & 2) && wal->nextwall >= 0) + wall[wal->nextwall].shade = wal->shade; + } + } + + j = headspritesect[sprite[i].sectnum]; + while (j >= 0) + { + if (sprite[j].cstat & 16) + { + if (sc->ceilingstat & 1) + sprite[j].shade = sc->ceilingshade; + else sprite[j].shade = sc->floorshade; + } + + j = nextspritesect[j]; + } + + if (t[4]) + deletesprite(i); + +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se05(int i, int FIRELASER) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + int j, l, q, m; + + int x, p = findplayer(s, &x); + if (x < 8192) + { + j = s->ang; + s->ang = getangle(s->x - ps[p].posx, s->y - ps[p].posy); + shoot(i, FIRELASER); + s->ang = j; + } + + if (s->owner == -1) //Start search + { + t[4] = 0; + l = 0x7fffffff; + while (1) //Find the shortest dist + { + s->owner = LocateTheLocator((short)t[4], -1); //t[0] hold sectnum + + if (s->owner == -1) break; + + m = ldist(&sprite[ps[p].i], &sprite[s->owner]); + + if (l > m) + { + q = s->owner; + l = m; + } + + t[4]++; + } + + s->owner = q; + s->zvel = ksgn(sprite[q].z - s->z) << 4; + } + + if (ldist(&sprite[s->owner], s) < 1024) + { + short ta; + ta = s->ang; + s->ang = getangle(ps[p].posx - s->x, ps[p].posy - s->y); + s->ang = ta; + s->owner = -1; + return; + + } + else s->xvel = 256; + + x = getangle(sprite[s->owner].x - s->x, sprite[s->owner].y - s->y); + q = getincangle(s->ang, x) >> 3; + s->ang += q; + + if (rnd(32)) + { + t[2] += q; + sc->ceilingshade = 127; + } + else + { + t[2] += + getincangle(t[2] + 512, getangle(ps[p].posx - s->x, ps[p].posy - s->y)) >> 2; + sc->ceilingshade = 0; + } + j = ifhitbyweapon(i); + if (j >= 0) + { + t[3]++; + if (t[3] == 5) + { + s->zvel += 1024; + FTA(7, &ps[myconnectindex]); + } + } + + s->z += s->zvel; + sc->ceilingz += s->zvel; + sector[t[0]].ceilingz += s->zvel; + ms(i); + setsprite(i, s->x, s->y, s->z); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se08(int i, bool checkhitag1) +{ + // work only if its moving + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + + int x, j = -1; + + if (hittype[i].temp_data[4]) + { + hittype[i].temp_data[4]++; + if (hittype[i].temp_data[4] > 8) + { + deletesprite(i); + return; + } + j = 1; + } + else j = getanimationgoal(&sc->ceilingz); + + if (j >= 0) + { + short sn; + + if ((sc->lotag & 0x8000) || hittype[i].temp_data[4]) + x = -t[3]; + else + x = t[3]; + + if (st == 9) x = -x; + + j = headspritestat[STAT_EFFECTOR]; + while (j >= 0) + { + if (((sprite[j].lotag) == st) && (sprite[j].hitag) == sh) + { + sn = sprite[j].sectnum; + int m = sprite[j].shade; + + auto wal = &wall[sector[sn].wallptr]; + + for (int l = sector[sn].wallnum; l > 0; l--, wal++) + { + if (wal->hitag != 1) + { + wal->shade += x; + + if (wal->shade < m) + wal->shade = m; + else if (wal->shade > hittype[j].temp_data[2]) + wal->shade = hittype[j].temp_data[2]; + + if (wal->nextwall >= 0) + if (wall[wal->nextwall].hitag != 1) + wall[wal->nextwall].shade = wal->shade; + } + } + + sector[sn].floorshade += x; + sector[sn].ceilingshade += x; + + if (sector[sn].floorshade < m) + sector[sn].floorshade = m; + else if (sector[sn].floorshade > hittype[j].temp_data[0]) + sector[sn].floorshade = hittype[j].temp_data[0]; + + if (sector[sn].ceilingshade < m) + sector[sn].ceilingshade = m; + else if (sector[sn].ceilingshade > hittype[j].temp_data[1]) + sector[sn].ceilingshade = hittype[j].temp_data[1]; + + if (checkhitag1 && sector[sn].hitag == 1) + sector[sn].ceilingshade = hittype[j].temp_data[1]; + + } + j = nextspritestat[j]; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se10(int i, const int* specialtags) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + + if ((sc->lotag & 0xff) == 27 || (sc->floorz > sc->ceilingz && (sc->lotag & 0xff) != 23) || sc->lotag == (short)32791) + { + int j = 1; + + if ((sc->lotag & 0xff) != 27) + for (int p = connecthead; p >= 0; p = connectpoint2[p]) + if (sc->lotag != 30 && sc->lotag != 31 && sc->lotag != 0) + if (s->sectnum == sprite[ps[p].i].sectnum) + j = 0; + + if (j == 1) + { + if (t[0] > sh) + { + if (specialtags) for (int i = 0; specialtags[i]; i++) + { + if (sector[s->sectnum].lotag == specialtags[i] && getanimationgoal(§or[s->sectnum].ceilingz) >= 0) + { + return; + } + } + activatebysector(s->sectnum, i); + t[0] = 0; + } + else t[0]++; + } + } + else t[0] = 0; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se11(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + if (t[5] > 0) + { + t[5]--; + return; + } + + if (t[4]) + { + int startwall, endwall; + + startwall = sc->wallptr; + endwall = startwall + sc->wallnum; + + for (int j = startwall; j < endwall; j++) + { + int k = headspritestat[STAT_ACTOR]; + while (k >= 0) + { + if (sprite[k].extra > 0 && badguy(&sprite[k]) && clipinsidebox(sprite[k].x, sprite[k].y, j, 256L) == 1) + return; + k = nextspritestat[k]; + } + + k = headspritestat[STAT_PLAYER]; + while (k >= 0) + { + if (sprite[k].owner >= 0 && clipinsidebox(sprite[k].x, sprite[k].y, j, 144L) == 1) + { + t[5] = 8; // Delay + k = (sprite[i].yvel >> 3) * t[3]; + t[2] -= k; + t[4] -= k; + ms(i); + setsprite(i, s->x, s->y, s->z); + return; + } + k = nextspritestat[k]; + } + } + + int k = (sprite[i].yvel >> 3) * t[3]; + t[2] += k; + t[4] += k; + ms(i); + setsprite(i, s->x, s->y, s->z); + + if (t[4] <= -511 || t[4] >= 512) + { + t[4] = 0; + t[2] &= 0xffffff00; + ms(i); + setsprite(i, s->x, s->y, s->z); + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se12(int i, int planeonly) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + if (t[0] == 3 || t[3] == 1) //Lights going off + { + sc->floorpal = 0; + sc->ceilingpal = 0; + + auto wal = &wall[sc->wallptr]; + for (int j = sc->wallnum; j > 0; j--, wal++) + if (wal->hitag != 1) + { + wal->shade = t[1]; + wal->pal = 0; + } + + sc->floorshade = t[1]; + sc->ceilingshade = t[2]; + t[0] = 0; + + int j = headspritesect[sprite[i].sectnum]; + while (j >= 0) + { + if (sprite[j].cstat & 16) + { + if (sc->ceilingstat & 1) + sprite[j].shade = sc->ceilingshade; + else sprite[j].shade = sc->floorshade; + } + j = nextspritesect[j]; + + } + + if (t[3] == 1) + { + deletesprite(i); + return; + } + } + if (t[0] == 1) //Lights flickering on + { + // planeonly 1 is RRRA SE47, planeonly 2 is SE48 + int compshade = planeonly == 2 ? sc->ceilingshade : sc->floorshade; + if (compshade > s->shade) + { + if (planeonly != 2) sc->floorpal = s->pal; + if (planeonly != 1) sc->ceilingpal = s->pal; + + if (planeonly != 2) sc->floorshade -= 2; + if (planeonly != 1) sc->ceilingshade -= 2; + + auto wal = &wall[sc->wallptr]; + for (int j = sc->wallnum; j > 0; j--, wal++) + if (wal->hitag != 1) + { + wal->pal = s->pal; + wal->shade -= 2; + } + } + else t[0] = 2; + + int j = headspritesect[sprite[i].sectnum]; + while (j >= 0) + { + if (sprite[j].cstat & 16) + { + if (sc->ceilingstat & 1) + sprite[j].shade = sc->ceilingshade; + else sprite[j].shade = sc->floorshade; + } + j = nextspritesect[j]; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se13(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + if (t[2]) + { + int j = (sprite[i].yvel << 5) | 1; + + if (s->ang == 512) + { + if (s->owner) + { + if (abs(t[0] - sc->ceilingz) >= j) + sc->ceilingz += sgn(t[0] - sc->ceilingz) * j; + else sc->ceilingz = t[0]; + } + else + { + if (abs(t[1] - sc->floorz) >= j) + sc->floorz += sgn(t[1] - sc->floorz) * j; + else sc->floorz = t[1]; + } + } + else + { + if (abs(t[1] - sc->floorz) >= j) + sc->floorz += sgn(t[1] - sc->floorz) * j; + else sc->floorz = t[1]; + if (abs(t[0] - sc->ceilingz) >= j) + sc->ceilingz += sgn(t[0] - sc->ceilingz) * j; + sc->ceilingz = t[0]; + } + + if (t[3] == 1) + { + //Change the shades + + t[3]++; + sc->ceilingstat ^= 1; + + if (s->ang == 512) + { + auto wal = &wall[sc->wallptr]; + for (j = sc->wallnum; j > 0; j--, wal++) + wal->shade = s->shade; + + sc->floorshade = s->shade; + + if (ps[0].one_parallax_sectnum >= 0) + { + sc->ceilingpicnum = + sector[ps[0].one_parallax_sectnum].ceilingpicnum; + sc->ceilingshade = + sector[ps[0].one_parallax_sectnum].ceilingshade; + } + } + } + t[2]++; + if (t[2] > 256) + { + deletesprite(i); + return; + } + } + + + if (t[2] == 4 && s->ang != 512) + for (int x = 0; x < 7; x++) RANDOMSCRAP(s, i); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se15(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + if (t[4]) + { + s->xvel = 16; + + if (t[4] == 1) //Opening + { + if (t[3] >= (sprite[i].yvel >> 3)) + { + t[4] = 0; //Turn off the sliders + callsound(s->sectnum, i); + return; + } + t[3]++; + } + else if (t[4] == 2) + { + if (t[3] < 1) + { + t[4] = 0; + callsound(s->sectnum, i); + return; + } + t[3]--; + } + + ms(i); + setsprite(i, s->x, s->y, s->z); + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se16(int i, int REACTOR, int REACTOR2) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + + t[2] += 32; + if (sc->floorz < sc->ceilingz) s->shade = 0; + + else if (sc->ceilingz < t[3]) + { + + //The following code check to see if + //there is any other sprites in the sector. + //If there isn't, then kill this sectoreffector + //itself..... + + int j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].picnum == REACTOR || sprite[j].picnum == REACTOR2) + return; + j = nextspritesect[j]; + } + if (j == -1) + { + deletesprite(i); + return; + } + else s->shade = 1; + } + + if (s->shade) sc->ceilingz += 1024; + else sc->ceilingz -= 512; + + ms(i); + setsprite(i, s->x, s->y, s->z); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se17(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + + int q = t[0] * (sprite[i].yvel << 2); + + sc->ceilingz += q; + sc->floorz += q; + + int j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].statnum == 10 && sprite[j].owner >= 0) + { + int p = sprite[j].yvel; + if (numplayers < 2) + ps[p].oposz = ps[p].posz; + ps[p].posz += q; + ps[p].truefz += q; + ps[p].truecz += q; + if (numplayers > 1) + ps[p].oposz = ps[p].posz; + } + if (sprite[j].statnum != 3) + { + hittype[j].bposz = sprite[j].z; + sprite[j].z += q; + } + + hittype[j].floorz = sc->floorz; + hittype[j].ceilingz = sc->ceilingz; + + j = nextspritesect[j]; + } + + if (t[0]) //If in motion + { + if (abs(sc->floorz - t[2]) <= sprite[i].yvel) + { + activatewarpelevators(i, 0); + return; + } + + if (t[0] == -1) + { + if (sc->floorz > t[3]) + return; + } + else if (sc->ceilingz < t[4]) return; + + if (t[1] == 0) return; + t[1] = 0; + + int j = headspritestat[STAT_EFFECTOR]; + while (j >= 0) + { + if (i != j && (sprite[j].lotag) == 17) + if ((sc->hitag - t[0]) == + (sector[sprite[j].sectnum].hitag) + && sh == (sprite[j].hitag)) + break; + j = nextspritestat[j]; + } + + if (j == -1) return; + + int k = headspritesect[s->sectnum]; + while (k >= 0) + { + int nextk = nextspritesect[k]; + + if (sprite[k].statnum == 10 && sprite[k].owner >= 0) + { + int p = sprite[k].yvel; + + ps[p].posx += sprite[j].x - s->x; + ps[p].posy += sprite[j].y - s->y; + ps[p].posz = sector[sprite[j].sectnum].floorz - (sc->floorz - ps[p].posz); + + hittype[k].floorz = sector[sprite[j].sectnum].floorz; + hittype[k].ceilingz = sector[sprite[j].sectnum].ceilingz; + + ps[p].bobposx = ps[p].oposx = ps[p].posx; + ps[p].bobposy = ps[p].oposy = ps[p].posy; + ps[p].oposz = ps[p].posz; + + ps[p].truefz = hittype[k].floorz; + ps[p].truecz = hittype[k].ceilingz; + ps[p].bobcounter = 0; + + changespritesect(k, sprite[j].sectnum); + ps[p].cursectnum = sprite[j].sectnum; + } + else if (sprite[k].statnum != 3) + { + sprite[k].x += + sprite[j].x - s->x; + sprite[k].y += + sprite[j].y - s->y; + sprite[k].z = sector[sprite[j].sectnum].floorz - + (sc->floorz - sprite[k].z); + + hittype[k].bposx = sprite[k].x; + hittype[k].bposy = sprite[k].y; + hittype[k].bposz = sprite[k].z; + + changespritesect(k, sprite[j].sectnum); + setsprite(k, sprite[k].x, sprite[k].y, sprite[k].z); + + hittype[k].floorz = sector[sprite[j].sectnum].floorz; + hittype[k].ceilingz = sector[sprite[j].sectnum].ceilingz; + + } + k = nextk; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se18(int i, bool morecheck) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + + if (t[0]) + { + if (s->pal) + { + if (s->ang == 512) + { + sc->ceilingz -= sc->extra; + if (sc->ceilingz <= t[1]) + { + sc->ceilingz = t[1]; + deletesprite(i); + return; + } + } + else + { + sc->floorz += sc->extra; + if (morecheck) + { + int j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if (ps[sprite[j].yvel].on_ground == 1) + ps[sprite[j].yvel].posz += sc->extra; + if (sprite[j].zvel == 0 && sprite[j].statnum != STAT_EFFECTOR && sprite[j].statnum != STAT_PROJECTILE) + { + hittype[j].bposz = sprite[j].z += sc->extra; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + if (sc->floorz >= t[1]) + { + sc->floorz = t[1]; + deletesprite(i); + return; + } + } + } + else + { + if (s->ang == 512) + { + sc->ceilingz += sc->extra; + if (sc->ceilingz >= s->z) + { + sc->ceilingz = s->z; + deletesprite(i); + return; + } + } + else + { + sc->floorz -= sc->extra; + if (morecheck) + { + int j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if (ps[sprite[j].yvel].on_ground == 1) + ps[sprite[j].yvel].posz -= sc->extra; + if (sprite[j].zvel == 0 && sprite[j].statnum != STAT_EFFECTOR && sprite[j].statnum != STAT_PROJECTILE) + { + hittype[j].bposz = sprite[j].z -= sc->extra; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + if (sc->floorz <= s->z) + { + sc->floorz = s->z; + deletesprite(i); + return; + } + } + } + + t[2]++; + if (t[2] >= s->hitag) + { + t[2] = 0; + t[0] = 0; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se19(int i, int BIGFORCE) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + int j, x, q; + + if (t[0]) + { + if (t[0] == 1) + { + t[0]++; + x = sc->wallptr; + q = x + sc->wallnum; + for (j = x; j < q; j++) + if (wall[j].overpicnum == BIGFORCE) + { + wall[j].cstat &= (128 + 32 + 8 + 4 + 2); + wall[j].overpicnum = 0; + if (wall[j].nextwall >= 0) + { + wall[wall[j].nextwall].overpicnum = 0; + wall[wall[j].nextwall].cstat &= (128 + 32 + 8 + 4 + 2); + } + } + } + + if (sc->ceilingz < sc->floorz) + sc->ceilingz += sprite[i].yvel; + else + { + sc->ceilingz = sc->floorz; + + j = headspritestat[STAT_EFFECTOR]; + while (j >= 0) + { + if (sprite[j].lotag == 0 && sprite[j].hitag == sh) + { + q = sprite[sprite[j].owner].sectnum; + sector[sprite[j].sectnum].floorpal = sector[sprite[j].sectnum].ceilingpal = + sector[q].floorpal; + sector[sprite[j].sectnum].floorshade = sector[sprite[j].sectnum].ceilingshade = + sector[q].floorshade; + + hittype[sprite[j].owner].temp_data[0] = 2; + } + j = nextspritestat[j]; + } + deletesprite(i); + return; + } + } + else //Not hit yet + { + j = ifhitsectors(s->sectnum); + if (j >= 0) + { + FTA(8, &ps[myconnectindex]); + + int l = headspritestat[STAT_EFFECTOR]; + while (l >= 0) + { + x = sprite[l].lotag & 0x7fff; + switch (x) + { + case 0: + if (sprite[l].hitag == sh) + { + q = sprite[l].sectnum; + sector[q].floorshade = + sector[q].ceilingshade = + sprite[sprite[l].owner].shade; + sector[q].floorpal = + sector[q].ceilingpal = + sprite[sprite[l].owner].pal; + } + break; + + case 1: + case 12: + //case 18: + case 19: + + if (sh == sprite[l].hitag) + if (hittype[l].temp_data[0] == 0) + { + hittype[l].temp_data[0] = 1; //Shut them all on + sprite[l].owner = i; + } + + break; + } + l = nextspritestat[l]; + } + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se20(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + + if (t[0] == 0) return; + if (t[0] == 1) s->xvel = 8; + else s->xvel = -8; + + if (s->xvel) //Moving + { + int x = (s->xvel * sintable[(s->ang + 512) & 2047]) >> 14; + int l = (s->xvel * sintable[s->ang & 2047]) >> 14; + + t[3] += s->xvel; + + s->x += x; + s->y += l; + + if (t[3] <= 0 || (t[3] >> 6) >= (sprite[i].yvel >> 6)) + { + s->x -= x; + s->y -= l; + t[0] = 0; + callsound(s->sectnum, i); + return; + } + + int j = headspritesect[s->sectnum]; + while (j >= 0) + { + int nextj = nextspritesect[j]; + + if (sprite[j].statnum != 3 && sprite[j].zvel == 0) + { + sprite[j].x += x; + sprite[j].y += l; + setsprite(j, sprite[j].x, sprite[j].y, sprite[j].z); + if (sector[sprite[j].sectnum].floorstat & 2) + if (sprite[j].statnum == 2) + makeitfall(j); + } + j = nextj; + } + + dragpoint((short)t[1], wall[t[1]].x + x, wall[t[1]].y + l); + dragpoint((short)t[2], wall[t[2]].x + x, wall[t[2]].y + l); + + for (int p = connecthead; p >= 0; p = connectpoint2[p]) + if (ps[p].cursectnum == s->sectnum && ps[p].on_ground) + { + ps[p].posx += x; + ps[p].posy += l; + + ps[p].oposx = ps[p].posx; + ps[p].oposy = ps[p].posy; + + setsprite(ps[p].i, ps[p].posx, ps[p].posy, ps[p].posz + PHEIGHT); + } + + sc->floorxpanning -= x >> 3; + sc->floorypanning -= l >> 3; + + sc->ceilingxpanning -= x >> 3; + sc->ceilingypanning -= l >> 3; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se21(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + int* lp; + + if (t[0] == 0) return; + + if (s->ang == 1536) + lp = &sc->ceilingz; + else + lp = &sc->floorz; + + if (t[0] == 1) //Decide if the s->sectnum should go up or down + { + s->zvel = ksgn(s->z - *lp) * (sprite[i].yvel << 4); + t[0]++; + } + + if (sc->extra == 0) + { + lp += s->zvel; + + if (abs(*lp - s->z) < 1024) + { + *lp = s->z; + deletesprite(i); + } + } + else sc->extra--; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se22(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + if (t[1]) + { + if (getanimationgoal(§or[t[0]].ceilingz) >= 0) + sc->ceilingz += sc->extra * 9; + else t[1] = 0; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se26(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int x, j, l; + + s->xvel = 32; + l = (s->xvel * sintable[(s->ang + 512) & 2047]) >> 14; + x = (s->xvel * sintable[s->ang & 2047]) >> 14; + + s->shade++; + if (s->shade > 7) + { + s->x = t[3]; + s->y = t[4]; + sc->floorz -= ((s->zvel * s->shade) - s->zvel); + s->shade = 0; + } + else + sc->floorz += s->zvel; + + j = headspritesect[s->sectnum]; + while (j >= 0) + { + int nextj = nextspritesect[j]; + if (sprite[j].statnum != 3 && sprite[j].statnum != 10) + { + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + + sprite[j].x += l; + sprite[j].y += x; + + sprite[j].z += s->zvel; + setsprite(j, sprite[j].x, sprite[j].y, sprite[j].z); + } + j = nextj; + } + + for (int p = connecthead; p >= 0; p = connectpoint2[p]) + if (sprite[ps[p].i].sectnum == s->sectnum && ps[p].on_ground) + { + ps[p].fric.x += l << 5; + ps[p].fric.y += x << 5; + ps[p].posz += s->zvel; + } + + ms(i); + setsprite(i, s->x, s->y, s->z); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se27(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + int st = s->lotag; + int sh = s->hitag; + int x, p; + + if (ud.recstat == 0) return; + + hittype[i].tempang = s->ang; + + p = findplayer(s, &x); + if (sprite[ps[p].i].extra > 0 && myconnectindex == screenpeek) + { + if (t[0] < 0) + { + ud.camerasprite = i; + t[0]++; + } + else if (ud.recstat == 2 && ps[p].newowner == -1) + { + if (cansee(s->x, s->y, s->z, sprite[i].sectnum, ps[p].posx, ps[p].posy, ps[p].posz, ps[p].cursectnum)) + { + if (x < (unsigned)sh) + { + ud.camerasprite = i; + t[0] = 999; + s->ang += getincangle(s->ang, getangle(ps[p].posx - s->x, ps[p].posy - s->y)) >> 3; + sprite[i].yvel = 100 + ((s->z - ps[p].posz) / 257); + + } + else if (t[0] == 999) + { + if (ud.camerasprite == i) + t[0] = 0; + else t[0] = -10; + ud.camerasprite = i; + + } + } + else + { + s->ang = getangle(ps[p].posx - s->x, ps[p].posy - s->y); + + if (t[0] == 999) + { + if (ud.camerasprite == i) + t[0] = 0; + else t[0] = -20; + ud.camerasprite = i; + } + } + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se32(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + + if (t[0] == 1) + { + // Choose dir + + if (t[2] == 1) // Retract + { + if (sprite[i].ang != 1536) + { + if (abs(sc->ceilingz - s->z) < + (sprite[i].yvel << 1)) + { + sc->ceilingz = s->z; + callsound(s->sectnum, i); + t[2] = 0; + t[0] = 0; + } + else sc->ceilingz += + sgn(s->z - sc->ceilingz) * sprite[i].yvel; + } + else + { + if (abs(sc->ceilingz - t[1]) < + (sprite[i].yvel << 1)) + { + sc->ceilingz = t[1]; + callsound(s->sectnum, i); + t[2] = 0; + t[0] = 0; + } + else sc->ceilingz += + sgn(t[1] - sc->ceilingz) * sprite[i].yvel; + } + return; + } + + if ((s->ang & 2047) == 1536) + { + if (abs(sc->ceilingz - s->z) < + (sprite[i].yvel << 1)) + { + t[0] = 0; + t[2] = !t[2]; + callsound(s->sectnum, i); + sc->ceilingz = s->z; + } + else sc->ceilingz += + sgn(s->z - sc->ceilingz) * sprite[i].yvel; + } + else + { + if (abs(sc->ceilingz - t[1]) < (sprite[i].yvel << 1)) + { + t[0] = 0; + t[2] = !t[2]; + callsound(s->sectnum, i); + } + else sc->ceilingz -= sgn(s->z - t[1]) * sprite[i].yvel; + } + } + +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se35(int i, int SMALLSMOKE, int EXPLOSION2) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + + if (sc->ceilingz > s->z) + for (int j = 0; j < 8; j++) + { + s->ang += krand() & 511; + int k = spawn(i, SMALLSMOKE); + sprite[k].xvel = 96 + (krand() & 127); + ssp(k, CLIPMASK0); + setsprite(k, sprite[k].x, sprite[k].y, sprite[k].z); + if (rnd(16)) + spawn(i, EXPLOSION2); + } + + switch (t[0]) + { + case 0: + sc->ceilingz += s->yvel; + if (sc->ceilingz > sc->floorz) + sc->floorz = sc->ceilingz; + if (sc->ceilingz > s->z + (32 << 8)) + t[0]++; + break; + case 1: + sc->ceilingz -= (s->yvel << 2); + if (sc->ceilingz < t[4]) + { + sc->ceilingz = t[4]; + t[0] = 0; + } + break; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se128(int i) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + + auto wal = &wall[t[2]]; + + if (wal->cstat | 32) + { + wal->cstat &= (255 - 32); + wal->cstat |= 16; + if (wal->nextwall >= 0) + { + wall[wal->nextwall].cstat &= (255 - 32); + wall[wal->nextwall].cstat |= 16; + } + } + else return; + + wal->overpicnum++; + if (wal->nextwall >= 0) + wall[wal->nextwall].overpicnum++; + + if (t[0] < t[1]) t[0]++; + else + { + wal->cstat &= (128 + 32 + 8 + 4 + 2); + if (wal->nextwall >= 0) + wall[wal->nextwall].cstat &= (128 + 32 + 8 + 4 + 2); + deletesprite(i); + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void handle_se130(int i, int countmax, int EXPLOSION2) +{ + spritetype* s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + auto sc = §or[s->sectnum]; + + if (t[0] > countmax) + { + deletesprite(i); + return; + } + else t[0]++; + + int x = sc->floorz - sc->ceilingz; + + if (rnd(64)) + { + int k = spawn(i, EXPLOSION2); + sprite[k].xrepeat = sprite[k].yrepeat = 2 + (krand() & 7); + sprite[k].z = sc->floorz - (krand() % x); + sprite[k].ang += 256 - (krand() % 511); + sprite[k].xvel = krand() & 127; + ssp(k, CLIPMASK0); + } +} + + END_DUKE_NS diff --git a/source/games/duke/src/actors.h b/source/games/duke/src/actors.h index 1a00b5dbb..d1c851f5e 100644 --- a/source/games/duke/src/actors.h +++ b/source/games/duke/src/actors.h @@ -273,8 +273,11 @@ inline int LocateTheLocator(int const tag, int const sectNum) return A_FindLocator(tag, sectNum); } -int A_CheckNoSE7Water(uspritetype const *pSprite, int sectNum, int sectLotag, int32_t *pOther); int A_CheckSwitchTile(int spriteNum); +inline int wallswitchcheck(int s) +{ + return A_CheckSwitchTile(s); +} int A_IncurDamage(int spriteNum); void A_AddToDeleteQueue(int spriteNum); void A_DeleteSprite(int spriteNum); @@ -375,6 +378,8 @@ inline int wakeup(int sn, int pn) } // shared functions +int ifhitsectors(int sn); +void ms(short i); void movecrane(int i, int crane); void movefountain(int i, int fountain); void moveflammable(int i, int tire, int box, int pool); @@ -407,6 +412,34 @@ void shell(int i, bool morecheck); void glasspieces(int i); void scrap(int i, int SCRAP1, int SCRAP6); +void handle_se00(int i, int LASERLINE); +void handle_se01(int i); +void handle_se14(int i, bool checkstat, int RPG, int JIBS6); +void handle_se30(int i, int JIBS6); +void handle_se02(int i); +void handle_se03(int i); +void handle_se04(int i); +void handle_se05(int i, int FIRELASER); +void handle_se08(int i, bool checkhitag1); +void handle_se10(int i, const int *); +void handle_se11(int i); +void handle_se12(int i, int planeonly = 0); +void handle_se13(int i); +void handle_se15(int i); +void handle_se16(int i, int REACTOR, int REACTOR2); +void handle_se17(int i); +void handle_se18(int i, bool morecheck); +void handle_se19(int i, int BIGFORCE); +void handle_se20(int i); +void handle_se21(int i); +void handle_se22(int i); +void handle_se26(int i); +void handle_se27(int i); +void handle_se32(int i); +void handle_se35(int i, int SMALLSMOKE, int EXPLOSION2); +void handle_se128(int i); +void handle_se130(int i, int countmax, int EXPLOSION2); + void respawn_rrra(int i, int j); void hitradius(short i, int r, int hp1, int hp2, int hp3, int hp4); diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 05cc71174..e16862bab 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -892,7 +892,7 @@ void movefallers_d(void) if (s->extra <= 0) { hittype[i].temp_data[0] = 1; - j = headspritestat[12]; + j = headspritestat[STAT_FALLER]; while (j >= 0) { if (sprite[j].hitag == sprite[i].hitag) @@ -1008,7 +1008,7 @@ static void movetripbomb(int i) sprite[j].xvel = 348; ssp(j, CLIPMASK0); - j = headspritestat[5]; + j = headspritestat[STAT_MISC]; while (j >= 0) { if (sprite[j].picnum == LASERLINE && s->hitag == sprite[j].hitag) @@ -1181,7 +1181,7 @@ static void movefireext(int i) if (s->hitag > 0) { - j = headspritestat[6]; + j = headspritestat[STAT_STANDABLE]; while (j >= 0) { if (s->hitag == sprite[j].hitag && (sprite[j].picnum == OOZFILTER || sprite[j].picnum == SEENINE)) @@ -1221,7 +1221,7 @@ static void moveviewscreen(int i) if (x < 2048) { #if 0 - if (SP == 1) + if (sprite[i].yvel == 1) camsprite = i; #endif } @@ -2381,7 +2381,7 @@ static void greenslime(int i) updatesector(ps[p].posx, ps[p].posy, &ps[p].cursectnum); setpal(&ps[p]); - j = headspritestat[1]; + j = headspritestat[STAT_ACTOR]; while (j >= 0) { if (sprite[j].picnum == CAMERA1) sprite[j].yvel = 0; @@ -2532,7 +2532,7 @@ static void greenslime(int i) case LIZMAN: case PIGCOP: case NEWBEAST: - if (ldist(s, &sprite[j]) < 768 && (klabs(s->z - sprite[j].z) < 8192)) //Gulp them + if (ldist(s, &sprite[j]) < 768 && (abs(s->z - sprite[j].z) < 8192)) //Gulp them { t[5] = j; t[0] = -2; @@ -2593,7 +2593,7 @@ static void greenslime(int i) s->yrepeat = 16 + (sintable[t[1] & 2047] >> 13); if (rnd(4) && (sector[sect].ceilingstat & 1) == 0 && - klabs(hittype[i].floorz - hittype[i].ceilingz) + abs(hittype[i].floorz - hittype[i].ceilingz) < (192 << 8)) { s->zvel = 0; @@ -2978,7 +2978,7 @@ void moveactors_d(void) unsigned short k; int nexti; - for (int i = headspritestat[1]; i >= 0; i = nexti) + for (int i = headspritestat[STAT_ACTOR]; i >= 0; i = nexti) { nexti = nextspritestat[i]; @@ -3025,7 +3025,7 @@ void moveactors_d(void) s->cstat = 32 + 128; k = 1; - j = headspritestat[1]; + j = headspritestat[STAT_ACTOR]; while (j >= 0) { if (sprite[j].lotag == s->lotag && @@ -3340,5 +3340,566 @@ void moveexplosions_d(void) // STATNUM 5 } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void moveeffectors_d(void) //STATNUM 3 +{ + int q = 0, l, x, st, j, * t; + int nexti, p, sh, nextj; + short k; + spritetype* s; + sectortype* sc; + walltype* wal; + + clearfriction(); + + + for (int i = headspritestat[STAT_EFFECTOR]; i >= 0; i = nexti) + { + nexti = nextspritestat[i]; + s = &sprite[i]; + + sc = §or[s->sectnum]; + st = s->lotag; + sh = s->hitag; + + t = &hittype[i].temp_data[0]; + + switch (st) + { + case SE_0_ROTATING_SECTOR: + handle_se00(i, LASERLINE); + break; + + case SE_1_PIVOT: //Nothing for now used as the pivot + handle_se01(i); + break; + + case SE_6_SUBWAY: + k = sc->extra; + + if (t[4] > 0) + { + t[4]--; + if (t[4] >= (k - (k >> 3))) + s->xvel -= (k >> 5); + if (t[4] > ((k >> 1) - 1) && t[4] < (k - (k >> 3))) + s->xvel = 0; + if (t[4] < (k >> 1)) + s->xvel += (k >> 5); + if (t[4] < ((k >> 1) - (k >> 3))) + { + t[4] = 0; + s->xvel = k; + } + } + else s->xvel = k; + + j = headspritestat[STAT_EFFECTOR]; + while (j >= 0) + { + if ((sprite[j].lotag == 14) && (sh == sprite[j].hitag) && (hittype[j].temp_data[0] == t[0])) + { + sprite[j].xvel = s->xvel; + // if( t[4] == 1 ) + { + if (hittype[j].temp_data[5] == 0) + hittype[j].temp_data[5] = dist(&sprite[j], s); + x = sgn(dist(&sprite[j], s) - hittype[j].temp_data[5]); + if (sprite[j].extra) + x = -x; + s->xvel += x; + } + hittype[j].temp_data[4] = t[4]; + } + j = nextspritestat[j]; + } + x = 0; + + + case SE_14_SUBWAY_CAR: + handle_se14(i, true, RPG, JIBS6); + break; + + case SE_30_TWO_WAY_TRAIN: + handle_se30(i, JIBS6); + break; + + + case SE_2_EARTHQUAKE: + handle_se02(i); + break; + + //Flashing sector lights after reactor EXPLOSION2 + case SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT: + handle_se03(i); + break; + + case SE_4_RANDOM_LIGHTS: + handle_se04(i); + break; + + //BOSS + case SE_5_BOSS: + handle_se05(i, FIRELASER); + break; + + case SE_8_UP_OPEN_DOOR_LIGHTS: + case SE_9_DOWN_OPEN_DOOR_LIGHTS: + handle_se08(i, false); + break; + + case SE_10_DOOR_AUTO_CLOSE: + { + static const int tags[] = { 20, 21, 22, 26, 0}; + handle_se10(i, tags); + break; + } + case SE_11_SWINGING_DOOR: + handle_se11(i); + break; + + case SE_12_LIGHT_SWITCH: + handle_se12(i); + break; + + case SE_13_EXPLOSIVE: + handle_se13(i); + break; + + case SE_15_SLIDING_DOOR: + handle_se15(i); + break; + + case SE_16_REACTOR: + handle_se16(i, REACTOR, REACTOR2); + break; + + case SE_17_WARP_ELEVATOR: + handle_se17(i); + break; + + case SE_18_INCREMENTAL_SECTOR_RISE_FALL: + handle_se18(i, true); + break; + + case SE_19_EXPLOSION_LOWERS_CEILING: + handle_se19(i, BIGFORCE); + break; + + case SE_20_STRETCH_BRIDGE: + handle_se20(i); + break; + + case SE_21_DROP_FLOOR: + handle_se21(i); + break; + + case SE_22_TEETH_DOOR: + handle_se22(i); + + break; + + case SE_24_CONVEYOR: + case 34: + + if (t[4]) break; + + x = (sprite[i].yvel * sintable[(s->ang + 512) & 2047]) >> 18; + l = (sprite[i].yvel * sintable[s->ang & 2047]) >> 18; + + k = 0; + + j = headspritesect[s->sectnum]; + while (j >= 0) + { + nextj = nextspritesect[j]; + if (sprite[j].zvel >= 0) + switch (sprite[j].statnum) + { + case 5: + switch (sprite[j].picnum) + { + case BLOODPOOL: + case PUKE: + case FOOTPRINTS: + case FOOTPRINTS2: + case FOOTPRINTS3: + case FOOTPRINTS4: + case BULLETHOLE: + case BLOODSPLAT1: + case BLOODSPLAT2: + case BLOODSPLAT3: + case BLOODSPLAT4: + sprite[j].xrepeat = sprite[j].yrepeat = 0; + j = nextj; + continue; + case LASERLINE: + j = nextj; + continue; + } + case 6: + if (sprite[j].picnum == TRIPBOMB) break; + case 1: + case 0: + if ( + sprite[j].picnum == BOLT1 || + sprite[j].picnum == BOLT1 + 1 || + sprite[j].picnum == BOLT1 + 2 || + sprite[j].picnum == BOLT1 + 3 || + sprite[j].picnum == SIDEBOLT1 || + sprite[j].picnum == SIDEBOLT1 + 1 || + sprite[j].picnum == SIDEBOLT1 + 2 || + sprite[j].picnum == SIDEBOLT1 + 3 || + wallswitchcheck(j) + ) + break; + + if (!(sprite[j].picnum >= CRANE && sprite[j].picnum <= (CRANE + 3))) + { + if (sprite[j].z > (hittype[j].floorz - (16 << 8))) + { + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + + sprite[j].x += x >> 2; + sprite[j].y += l >> 2; + + setsprite(j, sprite[j].x, sprite[j].y, sprite[j].z); + + if (sector[sprite[j].sectnum].floorstat & 2) + if (sprite[j].statnum == 2) + makeitfall(j); + } + } + break; + } + j = nextj; + } + + for (p = connecthead; p >= 0; p = connectpoint2[p]) + { + if (ps[p].cursectnum == s->sectnum && ps[p].on_ground) + { + if (abs(ps[p].pos.z - ps[p].truefz) < PHEIGHT + (9 << 8)) + { + ps[p].fric.x += x << 3; + ps[p].fric.y += l << 3; + } + } + } + + sc->floorxpanning += sprite[i].yvel >> 7; + + break; + + case 35: + handle_se35(i, SMALLSMOKE, EXPLOSION2); + break; + + case 25: //PISTONS + + if (t[4] == 0) break; + + if (sc->floorz <= sc->ceilingz) + s->shade = 0; + else if (sc->ceilingz <= t[3]) + s->shade = 1; + + if (s->shade) + { + sc->ceilingz += sprite[i].yvel << 4; + if (sc->ceilingz > sc->floorz) + sc->ceilingz = sc->floorz; + } + else + { + sc->ceilingz -= sprite[i].yvel << 4; + if (sc->ceilingz < t[3]) + sc->ceilingz = t[3]; + } + + break; + + case 26: + handle_se26(i); + break; + + case SE_27_DEMO_CAM: + handle_se27(i); + break; + case 28: + if (t[5] > 0) + { + t[5]--; + break; + } + + if (hittype[i].temp_data[0] == 0) + { + p = findplayer(s, &x); + if (x > 15500) + break; + hittype[i].temp_data[0] = 1; + hittype[i].temp_data[1] = 64 + (krand() & 511); + hittype[i].temp_data[2] = 0; + } + else + { + hittype[i].temp_data[2]++; + if (hittype[i].temp_data[2] > hittype[i].temp_data[1]) + { + hittype[i].temp_data[0] = 0; + ps[screenpeek].visibility = ud.const_visibility; + break; + } + else if (hittype[i].temp_data[2] == (hittype[i].temp_data[1] >> 1)) + spritesound(THUNDER, i); + else if (hittype[i].temp_data[2] == (hittype[i].temp_data[1] >> 3)) + spritesound(LIGHTNING_SLAP, i); + else if (hittype[i].temp_data[2] == (hittype[i].temp_data[1] >> 2)) + { + j = headspritestat[0]; + while (j >= 0) + { + if (sprite[j].picnum == NATURALLIGHTNING && sprite[j].hitag == s->hitag) + sprite[j].cstat |= 32768; + j = nextspritestat[j]; + } + } + else if (hittype[i].temp_data[2] > (hittype[i].temp_data[1] >> 3) && hittype[i].temp_data[2] < (hittype[i].temp_data[1] >> 2)) + { + if (cansee(s->x, s->y, s->z, s->sectnum, ps[screenpeek].posx, ps[screenpeek].posy, ps[screenpeek].posz, ps[screenpeek].cursectnum)) + j = 1; + else j = 0; + + if (rnd(192) && (hittype[i].temp_data[2] & 1)) + { + if (j) + ps[screenpeek].visibility = 0; + } + else if (j) + ps[screenpeek].visibility = ud.const_visibility; + + j = headspritestat[0]; + while (j >= 0) + { + if (sprite[j].picnum == NATURALLIGHTNING && sprite[j].hitag == s->hitag) + { + if (rnd(32) && (hittype[i].temp_data[2] & 1)) + { + sprite[j].cstat &= 32767; + spawn(j, SMALLSMOKE); + + p = findplayer(s, &x); + x = ldist(&sprite[ps[p].i], &sprite[j]); + if (x < 768) + { + if (S_CheckSoundPlaying(DUKE_LONGTERM_PAIN) < 1) + spritesound(DUKE_LONGTERM_PAIN, ps[p].i); + spritesound(SHORT_CIRCUIT, ps[p].i); + sprite[ps[p].i].extra -= 8 + (krand() & 7); + SetPlayerPal(&ps[p], PalEntry(32, 16, 0, 0)); + } + break; + } + else sprite[j].cstat |= 32768; + } + + j = nextspritestat[j]; + } + } + } + break; + case 29: + s->hitag += 64; + l = mulscale12((int)s->yvel, sintable[s->hitag & 2047]); + sc->floorz = s->z + l; + break; + case 31: // True Drop Floor + if (t[0] == 1) + { + // Choose dir + + if (t[3] > 0) + { + t[3]--; + break; + } + + if (t[2] == 1) // Retract + { + if (sprite[i].ang != 1536) + { + if (abs(sc->floorz - s->z) < sprite[i].yvel ) + { + sc->floorz = s->z; + t[2] = 0; + t[0] = 0; + t[3] = s->hitag; + callsound(s->sectnum, i); + } + else + { + l = sgn(s->z - sc->floorz) * sprite[i].yvel ; + sc->floorz += l; + + j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if (ps[sprite[j].yvel].on_ground == 1) + ps[sprite[j].yvel].posz += l; + if (sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4) + { + hittype[j].bposz = sprite[j].z += l; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + } + else + { + if (abs(sc->floorz - t[1]) < sprite[i].yvel ) + { + sc->floorz = t[1]; + callsound(s->sectnum, i); + t[2] = 0; + t[0] = 0; + t[3] = s->hitag; + } + else + { + l = sgn(t[1] - sc->floorz) * sprite[i].yvel ; + sc->floorz += l; + + j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if (ps[sprite[j].yvel].on_ground == 1) + ps[sprite[j].yvel].posz += l; + if (sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4) + { + hittype[j].bposz = sprite[j].z += l; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + } + break; + } + + if ((s->ang & 2047) == 1536) + { + if (abs(s->z - sc->floorz) < sprite[i].yvel ) + { + callsound(s->sectnum, i); + t[0] = 0; + t[2] = 1; + t[3] = s->hitag; + } + else + { + l = sgn(s->z - sc->floorz) * sprite[i].yvel ; + sc->floorz += l; + + j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if (ps[sprite[j].yvel].on_ground == 1) + ps[sprite[j].yvel].posz += l; + if (sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4) + { + hittype[j].bposz = sprite[j].z += l; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + } + else + { + if (abs(sc->floorz - t[1]) < sprite[i].yvel ) + { + t[0] = 0; + callsound(s->sectnum, i); + t[2] = 1; + t[3] = s->hitag; + } + else + { + l = sgn(s->z - t[1]) * sprite[i].yvel ; + sc->floorz -= l; + + j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if (ps[sprite[j].yvel].on_ground == 1) + ps[sprite[j].yvel].posz -= l; + if (sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4) + { + hittype[j].bposz = sprite[j].z -= l; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + } + } + break; + + case 32: // True Drop Ceiling + handle_se32(i); + break; + + case 33: + if (earthquaketime > 0 && (krand() & 7) == 0) + RANDOMSCRAP(s, i); + break; + case 36: + + if (t[0]) + { + if (t[0] == 1) + shoot(i, sc->extra); + else if (t[0] == 26 * 5) + t[0] = 0; + t[0]++; + } + break; + + case 128: //SE to control glass breakage + handle_se128(i); + break; + + case 130: + handle_se130(i, 80, EXPLOSION2); + break; + case 131: + handle_se130(i, 40, EXPLOSION2); + break; + } + } + + //Sloped sin-wave floors! + for (int i = headspritestat[STAT_EFFECTOR]; i >= 0; i = nextspritestat[i]) + { + s = &sprite[i]; + if (s->lotag != 29) continue; + sc = §or[s->sectnum]; + if (sc->wallnum != 4) continue; + wal = &wall[sc->wallptr + 2]; + alignflorslope(s->sectnum, wal->x, wal->y, sector[wal->nextsector].floorz); + } +} END_DUKE_NS diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index fad0798d4..7023a788f 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -850,7 +850,7 @@ void movefallers_r(void) if (s->extra <= 0) { hittype[i].temp_data[0] = 1; - j = headspritestat[12]; + j = headspritestat[STAT_FALLER]; while (j >= 0) { if (sprite[j].hitag == sprite[i].hitag) @@ -1661,7 +1661,7 @@ void movetransports_r(void) { char warpdir, warpspriteto; short i, j, k, p, sect, sectlotag, nexti, nextj; - long ll2, ll, onfloorz; + int ll2, ll, onfloorz; i = headspritestat[STAT_TRANSPORT]; //Transporters @@ -2469,7 +2469,7 @@ void rr_specialstats() sprite[i].z = sector[sprite[i].sectnum].floorz - 15168; sprite[i].extra = 0; sprite[i].picnum = RRTILE3410; - j = headspritestat[0]; + j = headspritestat[STAT_DEFAULT]; while (j >= 0) { nextj = nextspritestat[j]; @@ -2991,7 +2991,7 @@ void moveactors_r(void) } rr_specialstats(); - for (int i = headspritestat[1]; i >= 0; i = nexti) + for (int i = headspritestat[STAT_ACTOR]; i >= 0; i = nexti) { nexti = nextspritestat[i]; bool deleteafterexecute = false; // taking a cue here from RedNukem to not run scripts on deleted sprites. @@ -3493,5 +3493,537 @@ void moveexplosions_r(void) // STATNUM 5 } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void moveeffectors_r(void) //STATNUM 3 +{ + int l, x, st, j, * t; + int nexti, p, sh, nextj, ns, pn; + short k; + spritetype* s; + sectortype* sc; + walltype* wal; + + clearfriction(); + + + for (int i = headspritestat[STAT_EFFECTOR]; i >= 0; i = nexti) + { + nexti = nextspritestat[i]; + s = &sprite[i]; + + sc = §or[s->sectnum]; + st = s->lotag; + sh = s->hitag; + + t = &hittype[i].temp_data[0]; + + switch (st) + { + case SE_0_ROTATING_SECTOR: + handle_se00(i, -1); + break; + + case SE_1_PIVOT: //Nothing for now used as the pivot + handle_se01(i); + break; + + case SE_6_SUBWAY: + k = sc->extra; + + if (t[4] > 0) + { + t[4]--; + if (t[4] >= (k - (k >> 3))) + s->xvel -= (k >> 5); + if (t[4] > ((k >> 1) - 1) && t[4] < (k - (k >> 3))) + s->xvel = 0; + if (t[4] < (k >> 1)) + s->xvel += (k >> 5); + if (t[4] < ((k >> 1) - (k >> 3))) + { + t[4] = 0; + s->xvel = k; + if ((!isRRRA() || lastlevel) && hulkspawn) + { + hulkspawn--; + ns = spawn(i, HULK); + sprite[ns].z = sector[sprite[ns].sectnum].ceilingz; + sprite[ns].pal = 33; + if (!hulkspawn) + { + ns = EGS(s->sectnum, s->x, s->y, sector[s->sectnum].ceilingz + 119428, 3677, -8, 16, 16, 0, 0, 0, i, 5); + sprite[ns].cstat = 514; + sprite[ns].pal = 7; + sprite[ns].xrepeat = 80; + sprite[ns].yrepeat = 255; + ns = spawn(i, 296); + sprite[ns].cstat = 0; + sprite[ns].cstat |= 32768; + sprite[ns].z = sector[s->sectnum].floorz - 6144; + deletesprite(i); + break; + } + } + } + } + else + { + s->xvel = k; + j = headspritesect[s->sectnum]; + while (j >= 0) + { + nextj = nextspritesect[j]; + if (sprite[j].picnum == UFOBEAM) + if (ufospawn) + if (++ufocnt == 64) + { + ufocnt = 0; + ufospawn--; + if (!isRRRA()) + { + switch (krand() & 3) + { + default: + case 0: + pn = UFO1_RR; + break; + case 1: + pn = UFO2; + break; + case 2: + pn = UFO3; + break; + case 3: + pn = UFO4; + break; + } + } + else pn = UFO1_RRRA; + ns = spawn(i, pn); + sprite[ns].z = sector[sprite[ns].sectnum].ceilingz; + } + j = nextj; + } + } + + j = headspritestat[STAT_EFFECTOR]; + while (j >= 0) + { + if ((sprite[j].lotag == 14) && (sh == sprite[j].hitag) && (hittype[j].temp_data[0] == t[0])) + { + sprite[j].xvel = s->xvel; + // if( t[4] == 1 ) + { + if (hittype[j].temp_data[5] == 0) + hittype[j].temp_data[5] = dist(&sprite[j], s); + x = sgn(dist(&sprite[j], s) - hittype[j].temp_data[5]); + if (sprite[j].extra) + x = -x; + s->xvel += x; + } + hittype[j].temp_data[4] = t[4]; + } + j = nextspritestat[j]; + } + x = 0; + + + case SE_14_SUBWAY_CAR: + handle_se14(i, false, RPG, JIBS6); + break; + + case SE_30_TWO_WAY_TRAIN: + handle_se30(i, JIBS6); + break; + + + case SE_2_EARTHQUAKE: + handle_se02(i); + break; + + //Flashing sector lights after reactor EXPLOSION2 + case SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT: + handle_se03(i); + break; + + case SE_4_RANDOM_LIGHTS: + handle_se04(i); + break; + + //BOSS + case SE_5_BOSS: + handle_se05(i, FIRELASER); + break; + + case SE_8_UP_OPEN_DOOR_LIGHTS: + case SE_9_DOWN_OPEN_DOOR_LIGHTS: + handle_se08(i, true); + break; + + case SE_10_DOOR_AUTO_CLOSE: + + handle_se10(i, nullptr); + break; + case SE_11_SWINGING_DOOR: + handle_se11(i); + break; + + case SE_12_LIGHT_SWITCH: + handle_se12(i); + break; + + case SE_47_LIGHT_SWITCH: + if (isRRRA()) handle_se12(i, 1); + break; + + case SE_48_LIGHT_SWITCH: + if (isRRRA()) handle_se12(i, 2); + break; + + + case SE_13_EXPLOSIVE: + handle_se13(i); + break; + + case SE_15_SLIDING_DOOR: + handle_se15(i); + break; + + case SE_16_REACTOR: + handle_se16(i, REACTOR, REACTOR2); + break; + + case SE_17_WARP_ELEVATOR: + handle_se17(i); + break; + + case SE_18_INCREMENTAL_SECTOR_RISE_FALL: + handle_se18(i, true); + break; + + case SE_19_EXPLOSION_LOWERS_CEILING: + handle_se19(i, BIGFORCE); + break; + + case SE_20_STRETCH_BRIDGE: + handle_se20(i); + break; + + case SE_21_DROP_FLOOR: + handle_se21(i); + break; + + case SE_22_TEETH_DOOR: + handle_se22(i); + + break; + + case 156: + if (!isRRRA()) break; + case SE_24_CONVEYOR: + case 34: + + if (t[4]) break; + + x = (sprite[i].yvel * sintable[(s->ang + 512) & 2047]) >> 18; + l = (sprite[i].yvel * sintable[s->ang & 2047]) >> 18; + + k = 0; + + j = headspritesect[s->sectnum]; + while (j >= 0) + { + nextj = nextspritesect[j]; + if (sprite[j].zvel >= 0) + switch (sprite[j].statnum) + { + case 5: + switch (sprite[j].picnum) + { + case BLOODPOOL: + case FOOTPRINTS: + case FOOTPRINTS2: + case FOOTPRINTS3: + sprite[j].xrepeat = sprite[j].yrepeat = 0; + k = 1; + break; + case BULLETHOLE: + j = nextj; + continue; + } + case 6: + case 1: + case 0: + if ( + sprite[j].picnum == BOLT1 || + sprite[j].picnum == BOLT1 + 1 || + sprite[j].picnum == BOLT1 + 2 || + sprite[j].picnum == BOLT1 + 3 || + wallswitchcheck(j) + ) + break; + + if (!(sprite[j].picnum >= CRANE && sprite[j].picnum <= (CRANE + 3))) + { + if (sprite[j].z > (hittype[j].floorz - (16 << 8))) + { + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + + sprite[j].x += x >> 1; + sprite[j].y += l >> 1; + + setsprite(j, sprite[j].x, sprite[j].y, sprite[j].z); + + if (sector[sprite[j].sectnum].floorstat & 2) + if (sprite[j].statnum == 2) + makeitfall(j); + } + } + break; + } + j = nextj; + } + + for (p = connecthead; p >= 0; p = connectpoint2[p]) + { + if (ps[p].cursectnum == s->sectnum && ps[p].on_ground) + { + if (abs(ps[p].pos.z - ps[p].truefz) < PHEIGHT + (9 << 8)) + { + ps[p].fric.x += x << 3; + ps[p].fric.y += l << 3; + } + } + } + + sc->floorxpanning += sprite[i].yvel >> 7; + + break; + + case 35: + handle_se35(i, SMALLSMOKE, EXPLOSION2); + break; + + case 25: //PISTONS + + if (t[4] == 0) break; + + if (sc->floorz <= sc->ceilingz) + s->shade = 0; + else if (sc->ceilingz <= t[4]) + s->shade = 1; + + if (s->shade) + { + sc->ceilingz += sprite[i].yvel << 4; + if (sc->ceilingz > sc->floorz) + { + sc->ceilingz = sc->floorz; + if (isRRRA() && pistonsound) + spritesound(371, i); + } + } + else + { + sc->ceilingz -= sprite[i].yvel << 4; + if (sc->ceilingz < t[4]) + { + sc->ceilingz = t[4]; + if (isRRRA() && pistonsound) + spritesound(167, i); + } + } + + break; + + case 26: + handle_se26(i); + break; + + case SE_27_DEMO_CAM: + handle_se27(i); + break; + + case 29: + s->hitag += 64; + l = mulscale12((int)s->yvel, sintable[s->hitag & 2047]); + sc->floorz = s->z + l; + break; + + case 31: // True Drop Floor + if (t[0] == 1) + { + if (t[2] == 1) // Retract + { + if (sprite[i].ang != 1536) + { + if (abs(sc->floorz - s->z) < sprite[i].yvel ) + { + sc->floorz = s->z; + t[2] = 0; + t[0] = 0; + callsound(s->sectnum, i); + } + else + { + l = sgn(s->z - sc->floorz) * sprite[i].yvel ; + sc->floorz += l; + + j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if (ps[sprite[j].yvel].on_ground == 1) + ps[sprite[j].yvel].posz += l; + if (sprite[j].zvel == 0 && sprite[j].statnum != 3) + { + hittype[j].bposz = sprite[j].z += l; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + } + else + { + if (abs(sc->floorz - t[1]) < sprite[i].yvel ) + { + sc->floorz = t[1]; + callsound(s->sectnum, i); + t[2] = 0; + t[0] = 0; + } + else + { + l = sgn(t[1] - sc->floorz) * sprite[i].yvel ; + sc->floorz += l; + + j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if (ps[sprite[j].yvel].on_ground == 1) + ps[sprite[j].yvel].posz += l; + if (sprite[j].zvel == 0 && sprite[j].statnum != 3) + { + hittype[j].bposz = sprite[j].z += l; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + } + break; + } + + if ((s->ang & 2047) == 1536) + { + if (abs(s->z - sc->floorz) < sprite[i].yvel ) + { + callsound(s->sectnum, i); + t[0] = 0; + t[2] = 1; + } + else + { + l = sgn(s->z - sc->floorz) * sprite[i].yvel ; + sc->floorz += l; + + j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if (ps[sprite[j].yvel].on_ground == 1) + ps[sprite[j].yvel].posz += l; + if (sprite[j].zvel == 0 && sprite[j].statnum != 3) + { + hittype[j].bposz = sprite[j].z += l; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + } + else + { + if (abs(sc->floorz - t[1]) < sprite[i].yvel ) + { + t[0] = 0; + callsound(s->sectnum, i); + t[2] = 1; + } + else + { + l = sgn(s->z - t[1]) * sprite[i].yvel ; + sc->floorz -= l; + + j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].picnum == APLAYER && sprite[j].owner >= 0) + if (ps[sprite[j].yvel].on_ground == 1) + ps[sprite[j].yvel].posz -= l; + if (sprite[j].zvel == 0 && sprite[j].statnum != 3) + { + hittype[j].bposz = sprite[j].z -= l; + hittype[j].floorz = sc->floorz; + } + j = nextspritesect[j]; + } + } + } + } + break; + + case 32: // True Drop Ceiling + handle_se32(i); + break; + + case 33: + if (earthquaketime > 0 && (krand() & 7) == 0) + RANDOMSCRAP(s, i); + break; + case 36: + + if (t[0]) + { + if (t[0] == 1) + shoot(i, sc->extra); + else if (t[0] == 26 * 5) + t[0] = 0; + t[0]++; + } + break; + + case 128: //SE to control glass breakage + handle_se128(i); + break; + + case 130: + handle_se130(i, 80, EXPLOSION2); + break; + case 131: + handle_se130(i, 40, EXPLOSION2); + break; + } + } + + //Sloped sin-wave floors! + for (int i = headspritestat[STAT_EFFECTOR]; i >= 0; i = nextspritestat[i]) + { + s = &sprite[i]; + if (s->lotag != 29) continue; + sc = §or[s->sectnum]; + if (sc->wallnum != 4) continue; + wal = &wall[sc->wallptr + 2]; + alignflorslope(s->sectnum, wal->x, wal->y, sector[wal->nextsector].floorz); + } +} END_DUKE_NS diff --git a/source/games/duke/src/e_actors.cpp b/source/games/duke/src/e_actors.cpp index 4190fdd1a..3d88c99f9 100644 --- a/source/games/duke/src/e_actors.cpp +++ b/source/games/duke/src/e_actors.cpp @@ -50,12 +50,6 @@ void G_ClearCameraView(DukePlayer_t *ps) sprite[k].yvel = 0; } -// Manhattan distance between wall-point and sprite. -static FORCE_INLINE int32_t G_WallSpriteDist(uwalltype const * const wal, uspritetype const * const spr) -{ - return klabs(wal->x - spr->x) + klabs(wal->y - spr->y); -} - void hitradius(short i, int r, int hp1, int hp2, int hp3, int hp4); void A_RadiusDamage(int spriteNum, int blastRadius, int dmg1, int dmg2, int dmg3, int dmg4) @@ -63,71 +57,6 @@ void A_RadiusDamage(int spriteNum, int blastRadius, int dmg1, int dmg2, int dmg3 hitradius(spriteNum, blastRadius, dmg1, dmg2, dmg3, dmg4); } -// Check whether sprite is on/in a non-SE7 water sector. -// : if not NULL, the sector on the other side. -int A_CheckNoSE7Water(uspritetype const * const pSprite, int sectNum, int sectLotag, int32_t *pOther) -{ - if (sectLotag == ST_1_ABOVE_WATER || sectLotag == ST_2_UNDERWATER) - { - int const otherSect = - yax_getneighborsect(pSprite->x, pSprite->y, sectNum, sectLotag == ST_1_ABOVE_WATER ? YAX_FLOOR : YAX_CEILING); - int const otherLotag = (sectLotag == ST_1_ABOVE_WATER) ? ST_2_UNDERWATER : ST_1_ABOVE_WATER; - - // If submerging, the lower sector MUST have lotag 2. - // If emerging, the upper sector MUST have lotag 1. - // This way, the x/y coordinates where above/below water - // changes can happen are the same. - if (otherSect >= 0 && sector[otherSect].lotag == otherLotag) - { - if (pOther) - *pOther = otherSect; - return 1; - } - } - - return 0; -} - -// Check whether to do a z position update of sprite . -// Returns: -// 0 if no. -// 1 if yes, but stayed inside [actor[].ceilingz+1, actor[].floorz]. -// <0 if yes, but passed a TROR no-SE7 water boundary. -returnvalue-1 is the -// other-side sector number. -static int32_t A_CheckNeedZUpdate(int32_t spriteNum, int32_t zChange, int32_t *pZcoord) -{ - uspritetype const *const pSprite = (uspritetype *)&sprite[spriteNum]; - int const newZ = pSprite->z + (zChange >> 1); - - *pZcoord = newZ; - - if (newZ > actor[spriteNum].ceilingz && newZ <= actor[spriteNum].floorz) - return 1; - -#ifdef YAX_ENABLE - int const sectNum = pSprite->sectnum; - int const sectLotag = sector[sectNum].lotag; - int32_t otherSect; - - // Non-SE7 water. - // PROJECTILE_CHSECT - if ((zChange < 0 && sectLotag == ST_2_UNDERWATER) || (zChange > 0 && sectLotag == ST_1_ABOVE_WATER)) - { - if (A_CheckNoSE7Water(pSprite, sprite[spriteNum].sectnum, sectLotag, &otherSect)) - { - A_Spawn(spriteNum, TILE_WATERSPLASH2); - // NOTE: Don't tweak its z position afterwards like with - // SE7-induced projectile teleportation. It doesn't look good - // with TROR water. - - actor[spriteNum].flags |= SFLAG_DIDNOSE7WATER; - return -otherSect-1; - } - } -#endif - - return 0; -} int movesprite(short spritenum, int xchange, int ychange, int zchange, unsigned int cliptype); @@ -369,14 +298,6 @@ int A_IncurDamage(int const spriteNum) } -static void Proj_BounceOffWall(spritetype *s, int j) -{ - int k = getangle( - wall[wall[j].point2].x-wall[j].x, - wall[wall[j].point2].y-wall[j].y); - s->ang = ((k<<1) - s->ang)&2047; -} - int A_FindLocator(int const tag, int const sectNum) { for (bssize_t SPRITES_OF(STAT_LOCATOR, spriteNum)) @@ -389,2389 +310,6 @@ static void Proj_BounceOffWall(spritetype *s, int j) } -// i: SE spritenum -static void HandleSE31(int spriteNum, int setFloorZ, int spriteZ, int SEdir, int zDifference) -{ - const spritetype *pSprite = &sprite[spriteNum]; - sectortype *const pSector = §or[sprite[spriteNum].sectnum]; - int32_t *const pData = actor[spriteNum].t_data; - - if (klabs(pSector->floorz - spriteZ) < SP(spriteNum)) - { - if (setFloorZ) - pSector->floorz = spriteZ; - - pData[2] = SEdir; - pData[0] = 0; - if (!RR) - pData[3] = pSprite->hitag; - - A_CallSound(pSprite->sectnum, spriteNum); - } - else - { - int const zChange = ksgn(zDifference) * SP(spriteNum); - - pSector->floorz += zChange; - - for (bssize_t SPRITES_OF_SECT(pSprite->sectnum, j)) - { - if (sprite[j].picnum == TILE_APLAYER && sprite[j].owner >= 0) - { - int const playerNum = P_Get(j); - - if (g_player[playerNum].ps->on_ground == 1) - g_player[playerNum].ps->pos.z += zChange; - } - - if (sprite[j].zvel == 0 && sprite[j].statnum != STAT_EFFECTOR && (RR || sprite[j].statnum != STAT_PROJECTILE)) - { - sprite[j].z += zChange; - actor[j].bpos.z = sprite[j].z; - actor[j].floorz = pSector->floorz; - } - } - } -} - -// s: SE sprite -static void MaybeTrainKillPlayer(const spritetype *pSprite, int const setOPos) -{ - for (bssize_t TRAVERSE_CONNECT(playerNum)) - { - DukePlayer_t *const pPlayer = g_player[playerNum].ps; - - if (sprite[pPlayer->i].extra > 0) - { - int16_t playerSectnum = pPlayer->cursectnum; - - updatesector(pPlayer->pos.x, pPlayer->pos.y, &playerSectnum); - - if ((playerSectnum == -1 && !ud.clipping) || (pPlayer->cursectnum != pSprite->sectnum && playerSectnum == pSprite->sectnum)) - { - *(vec2_t *)pPlayer = *(vec2_t const *)pSprite; - - if (setOPos) - *(vec2_t *)&pPlayer->opos = *(vec2_t *)pPlayer; - - pPlayer->cursectnum = pSprite->sectnum; - - setsprite(pPlayer->i, (vec3_t const *)pSprite); - P_QuickKill(pPlayer); - } - } - } -} - -// i: SE spritenum -static void MaybeTrainKillEnemies(int const spriteNum, int const gutSpawnCnt) -{ - int findSprite = headspritesect[sprite[OW(spriteNum)].sectnum]; - - do - { - int const nextSprite = nextspritesect[findSprite]; - - if (sprite[findSprite].statnum == STAT_ACTOR && A_CheckEnemySprite(&sprite[findSprite])) - { - int16_t sectNum = sprite[findSprite].sectnum; - - updatesector(sprite[findSprite].x,sprite[findSprite].y,§Num); - - if (sprite[findSprite].extra >= 0 && sectNum == sprite[spriteNum].sectnum) - { - A_DoGutsDir(findSprite, TILE_JIBS6, gutSpawnCnt); - A_PlaySound(SQUISHED, findSprite); - A_DeleteSprite(findSprite); - } - } - - findSprite = nextSprite; - } - while (findSprite >= 0); -} - -ACTOR_STATIC void G_MoveEffectors(void) //STATNUM 3 -{ - int32_t q = 0, j, k, l, m, x; - int spriteNum = headspritestat[STAT_EFFECTOR]; - - for (native_t TRAVERSE_CONNECT(playerNum)) - { - vec2_t & fric = g_player[playerNum].ps->fric; - fric.x = fric.y = 0; - } - - while (spriteNum >= 0) - { - int const nextSprite = nextspritestat[spriteNum]; - spritetype *const pSprite = &sprite[spriteNum]; - int32_t playerDist; - int playerNum = A_FindPlayer(pSprite, &playerDist); - DukePlayer_t *const pPlayer = g_player[playerNum].ps; - - sectortype *const pSector = §or[pSprite->sectnum]; - int const spriteLotag = pSprite->lotag; - int const spriteHitag = pSprite->hitag; - int32_t *const pData = &actor[spriteNum].t_data[0]; - - switch (spriteLotag) - { - case SE_0_ROTATING_SECTOR: - { - int32_t zchange = 0; - - j = pSprite->owner; - - if ((uint16_t)sprite[j].lotag == UINT16_MAX) - DELETE_SPRITE_AND_CONTINUE(spriteNum); - - q = pSector->extra>>3; - l = 0; - - if (pSector->lotag == ST_30_ROTATE_RISE_BRIDGE) - { - q >>= 2; - - if (sprite[spriteNum].extra == 1) - { - if (actor[spriteNum].tempang < 256) - { - actor[spriteNum].tempang += 4; - if (actor[spriteNum].tempang >= 256) - A_CallSound(pSprite->sectnum,spriteNum); - if (pSprite->clipdist) l = 1; - else l = -1; - } - else actor[spriteNum].tempang = 256; - - if (pSector->floorz > pSprite->z) //z's are touching - { - pSector->floorz -= 512; - zchange = -512; - if (pSector->floorz < pSprite->z) - pSector->floorz = pSprite->z; - } - else if (pSector->floorz < pSprite->z) //z's are touching - { - pSector->floorz += 512; - zchange = 512; - if (pSector->floorz > pSprite->z) - pSector->floorz = pSprite->z; - } - } - else if (sprite[spriteNum].extra == 3) - { - if (actor[spriteNum].tempang > 0) - { - actor[spriteNum].tempang -= 4; - if (actor[spriteNum].tempang <= 0) - A_CallSound(pSprite->sectnum,spriteNum); - if (pSprite->clipdist) l = -1; - else l = 1; - } - else actor[spriteNum].tempang = 0; - - if (pSector->floorz > T4(spriteNum)) //z's are touching - { - pSector->floorz -= 512; - zchange = -512; - if (pSector->floorz < T4(spriteNum)) - pSector->floorz = T4(spriteNum); - } - else if (pSector->floorz < T4(spriteNum)) //z's are touching - { - pSector->floorz += 512; - zchange = 512; - if (pSector->floorz > T4(spriteNum)) - pSector->floorz = T4(spriteNum); - } - } - } - else - { - if (actor[j].t_data[0] == 0) break; - if (actor[j].t_data[0] == 2) DELETE_SPRITE_AND_CONTINUE(spriteNum); - - l = (sprite[j].ang > 1024) ? -1 : 1; - - if (pData[3] == 0) - pData[3] = ldist(pSprite,&sprite[j]); - pSprite->xvel = pData[3]; - pSprite->x = sprite[j].x; - pSprite->y = sprite[j].y; - } - - pSprite->ang += (l*q); - pData[2] += (l*q); - - if (l && (pSector->floorstat&64)) - { - for (TRAVERSE_CONNECT(playerNum)) - { - DukePlayer_t *const pPlayer = g_player[playerNum].ps; - - if (pPlayer->cursectnum == pSprite->sectnum && pPlayer->on_ground == 1) - { - pPlayer->q16ang += fix16_from_int(l*q); - pPlayer->q16ang &= 0x7FFFFFF; - - pPlayer->pos.z += zchange; - - vec2_t r; - rotatepoint(*(vec2_t *)&sprite[j],*(vec2_t *)&pPlayer->pos,(q*l),&r); - - pPlayer->bobpos.x += r.x-pPlayer->pos.x; - pPlayer->bobpos.y += r.y-pPlayer->pos.y; - - *(vec2_t *)&pPlayer->pos = r; - - if (sprite[pPlayer->i].extra <= 0) - *(vec2_t *)&sprite[pPlayer->i] = r; - } - } - - for (bssize_t SPRITES_OF_SECT(pSprite->sectnum, p)) - { - // KEEPINSYNC1 - if (sprite[p].statnum != STAT_EFFECTOR && sprite[p].statnum != STAT_PROJECTILE) - if (RR || sprite[p].picnum != TILE_LASERLINE) - { - if (sprite[p].picnum == TILE_APLAYER && sprite[p].owner >= 0) - continue; - - sprite[p].ang += (l*q); - sprite[p].ang &= 2047; - - sprite[p].z += zchange; - - rotatepoint(*(vec2_t *)&sprite[j], *(vec2_t *)&sprite[p], (q * l), (vec2_t *)&sprite[p].x); - } - } - - } - - A_MoveSector(spriteNum); - } - break; - - case SE_1_PIVOT: //Nothing for now used as the pivot - if (pSprite->owner == -1) //Init - { - pSprite->owner = spriteNum; - - for (SPRITES_OF(STAT_EFFECTOR, j)) - { - if (sprite[j].lotag == SE_19_EXPLOSION_LOWERS_CEILING && sprite[j].hitag == spriteHitag) - { - pData[0] = 0; - break; - } - } - } - break; - - case SE_6_SUBWAY: - k = pSector->extra; - - if (pData[4] > 0) - { - pData[4]--; - if (pData[4] >= (k-(k>>3))) - pSprite->xvel -= (k>>5); - if (pData[4] > ((k>>1)-1) && pData[4] < (k-(k>>3))) - pSprite->xvel = 0; - if (pData[4] < (k>>1)) - pSprite->xvel += (k>>5); - if (pData[4] < ((k>>1)-(k>>3))) - { - pData[4] = 0; - pSprite->xvel = k; - if (RR && (!RRRA || g_lastLevel) && g_hulkSpawn) - { - g_hulkSpawn--; - int newSprite = A_Spawn(spriteNum, TILE_HULK); - sprite[newSprite].z = sector[sprite[newSprite].sectnum].ceilingz; - sprite[newSprite].pal = 33; - if (!g_hulkSpawn) - { - newSprite = A_InsertSprite(pSprite->sectnum, pSprite->x, pSprite->y, - sector[pSprite->sectnum].ceilingz + 119428, TILE_RRTILE3677, -8, 16, 16, 0, 0, 0, spriteNum, STAT_MISC); - sprite[newSprite].cstat = 514; - sprite[newSprite].pal = 7; - sprite[newSprite].xrepeat = 80; - sprite[newSprite].yrepeat = 255; - newSprite = A_Spawn(spriteNum, TILE_RRTILE296); - sprite[newSprite].cstat = 0; - sprite[newSprite].cstat |= 32768; - sprite[newSprite].z = sector[pSprite->sectnum].floorz - 6144; - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - } - } - } - else - { - pSprite->xvel = k; - if (RR) - { - int otherSprite = headspritesect[pSprite->sectnum]; - while (otherSprite >= 0) - { - int const nextOtherSprite = nextspritesect[otherSprite]; - if (sprite[otherSprite].picnum == TILE_UFOBEAM) - if (g_ufoSpawn) - if (++g_ufoCnt == 64) - { - g_ufoCnt = 0; - g_ufoSpawn--; - int ufoTile = TILE_UFO1; - switch (krand2()&3) - { - case 0: - ufoTile = TILE_UFO1; - break; - case 1: - ufoTile = TILE_UFO2; - break; - case 2: - ufoTile = TILE_UFO3; - break; - case 3: - ufoTile = TILE_UFO4; - break; - } - if (RRRA) - ufoTile = TILE_UFO1; - int const newSprite = A_Spawn(spriteNum, ufoTile); - sprite[newSprite].z = sector[sprite[newSprite].sectnum].ceilingz; - } - otherSprite = nextOtherSprite; - } - } - } - - for (SPRITES_OF(STAT_EFFECTOR, j)) - { - if (sprite[j].lotag == SE_14_SUBWAY_CAR && spriteHitag == sprite[j].hitag && actor[j].t_data[0] == pData[0]) - { - sprite[j].xvel = pSprite->xvel; - // if( t[4] == 1 ) - { - if (actor[j].t_data[5] == 0) - actor[j].t_data[5] = dist(&sprite[j],pSprite); - x = ksgn(dist(&sprite[j],pSprite)-actor[j].t_data[5]); - if (sprite[j].extra) - x = -x; - pSprite->xvel += x; - } - actor[j].t_data[4] = pData[4]; - } - } - x = 0; // XXX: This assignment is dead? - fallthrough__; - - case SE_14_SUBWAY_CAR: - if (pSprite->owner==-1) - pSprite->owner = A_FindLocator((int16_t)pData[3],(int16_t)pData[0]); - - if (pSprite->owner == -1) - { - // debugging subway cars (mapping-wise) is freakin annoying - // let's at least have a helpful message... - Bsprintf(tempbuf,"Could not find any locators in sector %d" - " for SE# 6 or 14 with hitag %d.\n", (int)pData[0], (int)pData[3]); - G_GameExit(tempbuf); - } - - j = ldist(&sprite[pSprite->owner],pSprite); - - if (j < 1024L) - { - if (spriteLotag==SE_6_SUBWAY) - if (sprite[pSprite->owner].hitag&1) - pData[4]=pSector->extra; //Slow it down - pData[3]++; - pSprite->owner = A_FindLocator(pData[3],pData[0]); - if (pSprite->owner==-1) - { - pData[3]=0; - pSprite->owner = A_FindLocator(0,pData[0]); - } - } - - if (pSprite->xvel) - { -#ifdef YAX_ENABLE - int32_t firstrun = 1; -#endif - x = getangle(sprite[pSprite->owner].x-pSprite->x,sprite[pSprite->owner].y-pSprite->y); - q = G_GetAngleDelta(pSprite->ang,x)>>3; - - pData[2] += q; - pSprite->ang += q; - - if (pSprite->xvel == pSector->extra) - { - if (RR) - { - if (!S_CheckSoundPlaying(spriteNum,actor[spriteNum].lastv.x)) - A_PlaySound(actor[spriteNum].lastv.x,spriteNum); - } - if (!RR && (pSector->floorstat&1) == 0 && (pSector->ceilingstat&1) == 0) - { - if (!S_CheckSoundPlaying(spriteNum,actor[spriteNum].lastv.x)) - A_PlaySound(actor[spriteNum].lastv.x,spriteNum); - } - else if (ud.monsters_off == 0 && pSector->floorpal == 0 && (pSector->floorstat&1) && rnd(8)) - { - if (playerDist < 20480) - { - j = pSprite->ang; - pSprite->ang = getangle(pSprite->x-g_player[playerNum].ps->pos.x,pSprite->y-g_player[playerNum].ps->pos.y); - A_Shoot(spriteNum,TILE_RPG); - pSprite->ang = j; - } - } - } - - if (pSprite->xvel <= 64 && (RR || ((pSector->floorstat&1) == 0 && (pSector->ceilingstat&1) == 0))) - S_StopEnvSound(actor[spriteNum].lastv.x,spriteNum); - - if ((pSector->floorz-pSector->ceilingz) < (108<<8)) - { - if (ud.clipping == 0 && pSprite->xvel >= 192) - MaybeTrainKillPlayer(pSprite, 0); - } - - m = (pSprite->xvel*sintable[(pSprite->ang+512)&2047])>>14; - x = (pSprite->xvel*sintable[pSprite->ang&2047])>>14; - - for (TRAVERSE_CONNECT(playerNum)) - { - DukePlayer_t *const pPlayer = g_player[playerNum].ps; - - // might happen when squished into void space - if (pPlayer->cursectnum < 0) - break; - - if (sector[pPlayer->cursectnum].lotag != ST_2_UNDERWATER) - { - if (g_playerSpawnPoints[playerNum].sect == pSprite->sectnum) - { - g_playerSpawnPoints[playerNum].pos.x += m; - g_playerSpawnPoints[playerNum].pos.y += x; - } - - if (pSprite->sectnum == sprite[pPlayer->i].sectnum -#ifdef YAX_ENABLE - || (pData[9]>=0 && pData[9] == sprite[pPlayer->i].sectnum) -#endif - ) - { - rotatepoint(*(vec2_t *)pSprite, *(vec2_t *)&pPlayer->pos, q, (vec2_t *)&pPlayer->pos); - - pPlayer->pos.x += m; - pPlayer->pos.y += x; - - pPlayer->bobpos.x += m; - pPlayer->bobpos.y += x; - - pPlayer->q16ang += fix16_from_int(q); - pPlayer->q16ang &= 0x7FFFFFF; - - if (g_netServer || numplayers > 1) - { - pPlayer->opos.x = pPlayer->pos.x; - pPlayer->opos.y = pPlayer->pos.y; - } - if (sprite[pPlayer->i].extra <= 0) - { - sprite[pPlayer->i].x = pPlayer->pos.x; - sprite[pPlayer->i].y = pPlayer->pos.y; - } - } - } - } - - // NOTE: special loop handling - j = headspritesect[pSprite->sectnum]; - while (j >= 0) - { - // KEEPINSYNC2 - // XXX: underwater check? - if (sprite[j].statnum != STAT_PLAYER && sector[sprite[j].sectnum].lotag != ST_2_UNDERWATER && - (sprite[j].picnum != TILE_SECTOREFFECTOR || (sprite[j].lotag == SE_49_POINT_LIGHT||sprite[j].lotag == SE_50_SPOT_LIGHT)) - && sprite[j].picnum != TILE_LOCATORS) - { - rotatepoint(*(vec2_t *)pSprite,*(vec2_t *)&sprite[j],q,(vec2_t *)&sprite[j].x); - - sprite[j].x+= m; - sprite[j].y+= x; - - sprite[j].ang+=q; - - if (g_netServer || numplayers > 1) - { - actor[j].bpos.x = sprite[j].x; - actor[j].bpos.y = sprite[j].y; - } - } - j = nextspritesect[j]; -#ifdef YAX_ENABLE - if (j < 0) - { - if (pData[9]>=0 && firstrun) - { - firstrun = 0; - j = headspritesect[pData[9]]; - } - } -#endif - } - - A_MoveSector(spriteNum); - setsprite(spriteNum,(vec3_t *)pSprite); - - if ((pSector->floorz-pSector->ceilingz) < (108<<8)) - { - if (ud.clipping == 0 && pSprite->xvel >= 192) - MaybeTrainKillPlayer(pSprite, 1); - - MaybeTrainKillEnemies(spriteNum, 72); - } - } - - break; - - case SE_30_TWO_WAY_TRAIN: - if (pSprite->owner == -1) - { - pData[3] = !pData[3]; - pSprite->owner = A_FindLocator(pData[3],pData[0]); - } - else - { - - if (pData[4] == 1) // Starting to go - { - if (ldist(&sprite[pSprite->owner],pSprite) < (2048-128)) - pData[4] = 2; - else - { - if (pSprite->xvel == 0) - G_OperateActivators(pSprite->hitag+(!pData[3]),-1); - if (pSprite->xvel < 256) - pSprite->xvel += 16; - } - } - if (pData[4] == 2) - { - l = FindDistance2D(sprite[pSprite->owner].x-pSprite->x,sprite[pSprite->owner].y-pSprite->y); - - if (l <= 128) - pSprite->xvel = 0; - - if (pSprite->xvel > 0) - pSprite->xvel -= 16; - else - { - pSprite->xvel = 0; - G_OperateActivators(pSprite->hitag+(int16_t)pData[3],-1); - pSprite->owner = -1; - pSprite->ang += 1024; - pData[4] = 0; - G_OperateForceFields(spriteNum,pSprite->hitag); - - for (SPRITES_OF_SECT(pSprite->sectnum, j)) - { - if (sprite[j].picnum != TILE_SECTOREFFECTOR && sprite[j].picnum != TILE_LOCATORS) - { - actor[j].bpos.x = sprite[j].x; - actor[j].bpos.y = sprite[j].y; - } - } - - } - } - } - - if (pSprite->xvel) - { - l = (pSprite->xvel*sintable[(pSprite->ang+512)&2047])>>14; - x = (pSprite->xvel*sintable[pSprite->ang&2047])>>14; - - if ((pSector->floorz-pSector->ceilingz) < (108<<8)) - if (ud.clipping == 0) - MaybeTrainKillPlayer(pSprite, 0); - - for (int TRAVERSE_CONNECT(playerNum)) - { - DukePlayer_t *const pPlayer = g_player[playerNum].ps; - - if (sprite[pPlayer->i].sectnum == pSprite->sectnum) - { - pPlayer->pos.x += l; - pPlayer->pos.y += x; - - if (g_netServer || numplayers > 1) - { - pPlayer->opos.x = pPlayer->pos.x; - pPlayer->opos.y = pPlayer->pos.y; - } - - pPlayer->bobpos.x += l; - pPlayer->bobpos.y += x; - } - - if (g_playerSpawnPoints[playerNum].sect == pSprite->sectnum) - { - g_playerSpawnPoints[playerNum].pos.x += l; - g_playerSpawnPoints[playerNum].pos.y += x; - } - } - - for (SPRITES_OF_SECT(pSprite->sectnum, j)) - { - // TODO: replace some checks for SE 49/50 with statnum LIGHT instead? - if ((sprite[j].picnum != TILE_SECTOREFFECTOR || sprite[j].lotag==SE_49_POINT_LIGHT || sprite[j].lotag==SE_50_SPOT_LIGHT) - && sprite[j].picnum != TILE_LOCATORS) - { - if (numplayers < 2 && !g_netServer) - { - actor[j].bpos.x = sprite[j].x; - actor[j].bpos.y = sprite[j].y; - } - - sprite[j].x += l; - sprite[j].y += x; - - if (g_netServer || numplayers > 1) - { - actor[j].bpos.x = sprite[j].x; - actor[j].bpos.y = sprite[j].y; - } - } - } - - A_MoveSector(spriteNum); - setsprite(spriteNum,(vec3_t *)pSprite); - - if (pSector->floorz-pSector->ceilingz < (108<<8)) - { - if (ud.clipping == 0) - MaybeTrainKillPlayer(pSprite, 1); - - MaybeTrainKillEnemies(spriteNum, 24); - } - } - - break; - - - case SE_2_EARTHQUAKE://Quakes - if (pData[4] > 0 && pData[0] == 0) - { - if (pData[4] < spriteHitag) - pData[4]++; - else pData[0] = 1; - } - - if (pData[0] > 0) - { - pData[0]++; - - pSprite->xvel = 3; - - if (pData[0] > 96) - { - pData[0] = -1; //Stop the quake - pData[4] = -1; - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - else - { - if ((pData[0]&31) == 8) - { - g_earthquakeTime = 48; - A_PlaySound(EARTHQUAKE,g_player[screenpeek].ps->i); - } - - pSector->floorheinum = (klabs(pSector->floorheinum - pData[5]) < 8) - ? pData[5] - : pSector->floorheinum + (ksgn(pData[5] - pSector->floorheinum) << 4); - } - - vec2_t const vect = { (pSprite->xvel * sintable[(pSprite->ang + 512) & 2047]) >> 14, - (pSprite->xvel * sintable[pSprite->ang & 2047]) >> 14 }; - - for (TRAVERSE_CONNECT(playerNum)) - { - DukePlayer_t *const pPlayer = g_player[playerNum].ps; - - if (pPlayer->cursectnum == pSprite->sectnum && pPlayer->on_ground) - { - pPlayer->pos.x += vect.x; - pPlayer->pos.y += vect.y; - - pPlayer->bobpos.x += vect.x; - pPlayer->bobpos.y += vect.y; - } - } - - for (bssize_t nextSprite, SPRITES_OF_SECT_SAFE(pSprite->sectnum, sectSprite, nextSprite)) - { - if (sprite[sectSprite].picnum != TILE_SECTOREFFECTOR) - { - sprite[sectSprite].x+=vect.x; - sprite[sectSprite].y+=vect.y; - setsprite(sectSprite,(vec3_t *)&sprite[sectSprite]); - } - } - - A_MoveSector(spriteNum); - setsprite(spriteNum,(vec3_t *)pSprite); - } - break; - - //Flashing sector lights after reactor TILE_EXPLOSION2 - - case SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT: - { - if (pData[4] == 0) break; - - // if(t[5] > 0) { t[5]--; break; } - - if ((tabledivide32_noinline(g_globalRandom, spriteHitag+1)&31) < 4 && !pData[2]) - { - // t[5] = 4+(g_globalRandom&7); - pSector->ceilingpal = pSprite->owner >> 8; - pSector->floorpal = pSprite->owner & 0xff; - pData[0] = pSprite->shade + (g_globalRandom & 15); - } - else - { - // t[5] = 4+(g_globalRandom&3); - pSector->ceilingpal = pSprite->pal; - pSector->floorpal = pSprite->pal; - pData[0] = pData[3]; - } - - pSector->ceilingshade = pData[0]; - pSector->floorshade = pData[0]; - - walltype *pWall = &wall[pSector->wallptr]; - - for (x=pSector->wallnum; x > 0; x--,pWall++) - { - if (pWall->hitag != 1) - { - pWall->shade = pData[0]; - - if ((pWall->cstat & 2) && pWall->nextwall >= 0) - wall[pWall->nextwall].shade = pWall->shade; - } - } - - break; - } - - case SE_4_RANDOM_LIGHTS: - { - // See A_Spawn(): - // s->owner: original ((ceilingpal<<8) | floorpal) - // t[2]: original floor shade - // t[3]: max wall shade - int lightFlag; - - if ((tabledivide32_noinline(g_globalRandom, spriteHitag+1)&31) < 4) - { - pData[1] = pSprite->shade + (g_globalRandom & 15); // Got really bright - pData[0] = pSprite->shade + (g_globalRandom & 15); - pSector->ceilingpal = pSprite->owner >> 8; - pSector->floorpal = pSprite->owner & 0xff; - lightFlag = 1; - } - else - { - pData[1] = pData[2]; - pData[0] = pData[3]; - - pSector->ceilingpal = pSprite->pal; - pSector->floorpal = pSprite->pal; - - lightFlag = 0; - } - - pSector->floorshade = pData[1]; - pSector->ceilingshade = pData[1]; - - walltype *pWall = &wall[pSector->wallptr]; - - for (x=pSector->wallnum; x > 0; x--,pWall++) - { - if (lightFlag) pWall->pal = (pSprite->owner&0xff); - else pWall->pal = pSprite->pal; - - if (pWall->hitag != 1) - { - pWall->shade = pData[0]; - if ((pWall->cstat&2) && pWall->nextwall >= 0) - wall[pWall->nextwall].shade = pWall->shade; - } - } - - for (bssize_t SPRITES_OF_SECT(SECT(spriteNum), sectSprite)) - { - if (sprite[sectSprite].cstat&16) - sprite[sectSprite].shade = (pSector->ceilingstat & 1) ? pSector->ceilingshade : pSector->floorshade; - } - - if (pData[4]) - DELETE_SPRITE_AND_CONTINUE(spriteNum); - - break; - } - - //BOSS - case SE_5: - { - if (playerDist < 8192) - { - int const saveAng = pSprite->ang; - pSprite->ang = getangle(pSprite->x - pPlayer->pos.x, pSprite->y - pPlayer->pos.y); - A_Shoot(spriteNum, TILE_FIRELASER); - pSprite->ang = saveAng; - } - - if (pSprite->owner==-1) //Start search - { - pData[4] = 0; - int closestLocatorDist = INT32_MAX; - int closestLocator = pSprite->owner; - - //Find the shortest dist - do - { - pSprite->owner = A_FindLocator((int16_t)pData[4], -1); // t[0] hold sectnum - - if (pSprite->owner == -1) - break; - - int const locatorDist = ldist(&sprite[pPlayer->i],&sprite[pSprite->owner]); - - if (closestLocatorDist > locatorDist) - { - closestLocator = pSprite->owner; - closestLocatorDist = locatorDist; - } - - pData[4]++; - } - while (1); - - pSprite->owner = closestLocator; - pSprite->zvel = ksgn(sprite[closestLocator].z - pSprite->z) << 4; - } - - if (ldist(&sprite[pSprite->owner],pSprite) < 1024) - { - pSprite->owner = -1; - goto next_sprite; - } - else pSprite->xvel=256; - - int const angInc = G_GetAngleDelta(pSprite->ang, getangle(sprite[pSprite->owner].x-pSprite->x, - sprite[pSprite->owner].y-pSprite->y))>>3; - pSprite->ang += angInc; - - if (rnd(32)) - { - pData[2] += angInc; - pSector->ceilingshade = 127; - } - else - { - pData[2] += G_GetAngleDelta(pData[2] + 512, getangle(pPlayer->pos.x - pSprite->x, pPlayer->pos.y - pSprite->y)) >> 2; - pSector->ceilingshade = 0; - } - - if (A_IncurDamage(spriteNum) >= 0) - { - if (++pData[3] == 5) - { - pSprite->zvel += 1024; - P_DoQuote(QUOTE_WASTED, g_player[myconnectindex].ps); - } - } - - pSprite->z += pSprite->zvel; - pSector->ceilingz += pSprite->zvel; - sector[pData[0]].ceilingz += pSprite->zvel; - - A_MoveSector(spriteNum); - setsprite(spriteNum, (vec3_t *)pSprite); - break; - } - - case SE_8_UP_OPEN_DOOR_LIGHTS: - case SE_9_DOWN_OPEN_DOOR_LIGHTS: - { - - // work only if its moving - - int animGoal = -1; - - if (actor[spriteNum].t_data[4]) - { - if (++actor[spriteNum].t_data[4] > 8) - DELETE_SPRITE_AND_CONTINUE(spriteNum); - - animGoal = 1; - } - else animGoal = GetAnimationGoal(&pSector->ceilingz); - - if (animGoal >= 0) - { - int shadeInc = ((pSector->lotag & 0x8000u) || actor[spriteNum].t_data[4]) ? -pData[3] : pData[3]; - - if (spriteLotag == SE_9_DOWN_OPEN_DOOR_LIGHTS) - shadeInc = -shadeInc; - - for (bssize_t SPRITES_OF(STAT_EFFECTOR, sectorEffector)) - { - if (sprite[sectorEffector].lotag == spriteLotag && sprite[sectorEffector].hitag == spriteHitag) - { - int const sectNum = sprite[sectorEffector].sectnum; - int const spriteShade = sprite[sectorEffector].shade; - - walltype *pWall = &wall[sector[sectNum].wallptr]; - - for (bsize_t l=sector[sectNum].wallnum; l>0; l--, pWall++) - { - if (pWall->hitag == 1) - continue; - - pWall->shade += shadeInc; - - if (pWall->shade < spriteShade) - pWall->shade = spriteShade; - else if (pWall->shade > actor[sectorEffector].t_data[2]) - pWall->shade = actor[sectorEffector].t_data[2]; - - if (pWall->nextwall >= 0 && wall[pWall->nextwall].hitag != 1) - wall[pWall->nextwall].shade = pWall->shade; - } - - sector[sectNum].floorshade += shadeInc; - sector[sectNum].ceilingshade += shadeInc; - - if (sector[sectNum].floorshade < spriteShade) - sector[sectNum].floorshade = spriteShade; - else if (sector[sectNum].floorshade > actor[sectorEffector].t_data[0]) - sector[sectNum].floorshade = actor[sectorEffector].t_data[0]; - - if (sector[sectNum].ceilingshade < spriteShade) - sector[sectNum].ceilingshade = spriteShade; - else if (sector[sectNum].ceilingshade > actor[sectorEffector].t_data[1]) - sector[sectNum].ceilingshade = actor[sectorEffector].t_data[1]; - - if (RR && sector[sectNum].hitag == 1) - sector[sectNum].ceilingshade = actor[sectorEffector].t_data[1]; - } - } - } - break; - } - - case SE_10_DOOR_AUTO_CLOSE: - // XXX: 32791, what the hell? - if ((pSector->lotag&0xff) == ST_27_STRETCH_BRIDGE || (pSector->floorz > pSector->ceilingz && (pSector->lotag&0xff) != ST_23_SWINGING_DOOR) || pSector->lotag == (int16_t)32791u) - { - j = 1; - - if ((pSector->lotag&0xff) != ST_27_STRETCH_BRIDGE) - for (bssize_t TRAVERSE_CONNECT(playerNum)) - if (pSector->lotag != ST_30_ROTATE_RISE_BRIDGE && pSector->lotag != ST_31_TWO_WAY_TRAIN && pSector->lotag != 0 - && pSprite->sectnum == sprite[g_player[playerNum].ps->i].sectnum) - j = 0; - - if (j == 1) - { - if (pData[0] > spriteHitag) - switch (sector[pSprite->sectnum].lotag) - { - case ST_20_CEILING_DOOR: - case ST_21_FLOOR_DOOR: - case ST_22_SPLITTING_DOOR: - case ST_26_SPLITTING_ST_DOOR: - if (!RR && GetAnimationGoal(§or[pSprite->sectnum].ceilingz) >= 0) - break; - fallthrough__; - default: - G_ActivateBySector(pSprite->sectnum,spriteNum); - pData[0] = 0; - break; - } - else pData[0]++; - } - } - else pData[0]=0; - break; - - case SE_11_SWINGING_DOOR: //Swingdoor - - if (pData[5] > 0) - { - pData[5]--; - break; - } - - if (pData[4]) - { - int const endWall = pSector->wallptr+pSector->wallnum; - - l = (SP(spriteNum) >> 3) * pData[3]; - for (j=pSector->wallptr; j 0 && A_CheckEnemySprite(&sprite[k]) - && clipinsidebox((vec2_t *)&sprite[k], j, 256) == 1) - goto next_sprite; - } - for (SPRITES_OF(STAT_PLAYER, k)) - { - if (sprite[k].owner >= 0 && clipinsidebox((vec2_t *)&sprite[k], j, 144) == 1) - { - pData[5] = 8; // Delay - pData[2] -= l; - pData[4] -= l; - A_MoveSector(spriteNum); - setsprite(spriteNum, (vec3_t *)pSprite); - goto next_sprite; - } - } - } - - pData[2] += l; - pData[4] += l; - A_MoveSector(spriteNum); - setsprite(spriteNum, (vec3_t *)pSprite); - - if (pData[4] <= -511 || pData[4] >= 512) - { - pData[4] = 0; - pData[2] &= 0xffffff00; - A_MoveSector(spriteNum); - setsprite(spriteNum, (vec3_t *) pSprite); - break; - } - } - break; - - case SE_12_LIGHT_SWITCH: - if (pData[0] == 3 || pData[3] == 1) //Lights going off - { - pSector->floorpal = 0; - pSector->ceilingpal = 0; - - walltype *pWall = &wall[pSector->wallptr]; - - for (j = pSector->wallnum; j > 0; j--, pWall++) - { - if (pWall->hitag != 1) - { - pWall->shade = pData[1]; - pWall->pal = 0; - } - } - - pSector->floorshade = pData[1]; - pSector->ceilingshade = pData[2]; - pData[0] = 0; - - for (SPRITES_OF_SECT(SECT(spriteNum), j)) - { - if (sprite[j].cstat & 16) - sprite[j].shade = (pSector->ceilingstat & 1) ? pSector->ceilingshade : pSector->floorshade; - } - - if (pData[3] == 1) - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - - if (pData[0] == 1) //Lights flickering on - { - if (pSector->floorshade > pSprite->shade) - { - pSector->floorpal = pSprite->pal; - pSector->ceilingpal = pSprite->pal; - - pSector->floorshade -= 2; - pSector->ceilingshade -= 2; - - walltype *pWall = &wall[pSector->wallptr]; - for (j = pSector->wallnum; j > 0; j--, pWall++) - { - if (pWall->hitag != 1) - { - pWall->pal = pSprite->pal; - pWall->shade -= 2; - } - } - } - else pData[0] = 2; - - for (SPRITES_OF_SECT(SECT(spriteNum), j)) - { - if (sprite[j].cstat&16) - { - if (sprite[j].cstat & 16) - sprite[j].shade = (pSector->ceilingstat & 1) ? pSector->ceilingshade : pSector->floorshade; - } - } - } - break; - - case 47: - if (!RRRA) - break; - if (pData[0] == 3 || pData[3] == 1) //Lights going off - { - pSector->floorpal = 0; - pSector->ceilingpal = 0; - - walltype *pWall = &wall[pSector->wallptr]; - - for (j = pSector->wallnum; j > 0; j--, pWall++) - { - if (pWall->hitag != 1) - { - pWall->shade = pData[1]; - pWall->pal = 0; - } - } - - pSector->floorshade = pData[1]; - pSector->ceilingshade = pData[2]; - pData[0] = 0; - - for (SPRITES_OF_SECT(SECT(spriteNum), j)) - { - if (sprite[j].cstat & 16) - sprite[j].shade = (pSector->ceilingstat & 1) ? pSector->ceilingshade : pSector->floorshade; - } - - if (pData[3] == 1) - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - - if (pData[0] == 1) //Lights flickering on - { - if (pSector->floorshade > pSprite->shade) - { - pSector->floorpal = pSprite->pal; - - pSector->floorshade -= 2; - - walltype *pWall = &wall[pSector->wallptr]; - for (j = pSector->wallnum; j > 0; j--, pWall++) - { - if (pWall->hitag != 1) - { - pWall->pal = pSprite->pal; - pWall->shade -= 2; - } - } - } - else pData[0] = 2; - - for (SPRITES_OF_SECT(SECT(spriteNum), j)) - { - if (sprite[j].cstat&16) - { - if (sprite[j].cstat & 16) - sprite[j].shade = (pSector->ceilingstat & 1) ? pSector->ceilingshade : pSector->floorshade; - } - } - } - break; - - case 48: - if (!RRRA) - break; - if (pData[0] == 3 || pData[3] == 1) //Lights going off - { - pSector->floorpal = 0; - pSector->ceilingpal = 0; - - walltype *pWall = &wall[pSector->wallptr]; - - for (j = pSector->wallnum; j > 0; j--, pWall++) - { - if (pWall->hitag != 1) - { - pWall->shade = pData[1]; - pWall->pal = 0; - } - } - - pSector->floorshade = pData[1]; - pSector->ceilingshade = pData[2]; - pData[0] = 0; - - for (SPRITES_OF_SECT(SECT(spriteNum), j)) - { - if (sprite[j].cstat & 16) - sprite[j].shade = (pSector->ceilingstat & 1) ? pSector->ceilingshade : pSector->floorshade; - } - - if (pData[3] == 1) - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - - if (pData[0] == 1) //Lights flickering on - { - if (pSector->ceilingshade > pSprite->shade) - { - pSector->ceilingpal = pSprite->pal; - - pSector->ceilingshade -= 2; - - walltype *pWall = &wall[pSector->wallptr]; - for (j = pSector->wallnum; j > 0; j--, pWall++) - { - if (pWall->hitag != 1) - { - pWall->pal = pSprite->pal; - pWall->shade -= 2; - } - } - } - else pData[0] = 2; - - for (SPRITES_OF_SECT(SECT(spriteNum), j)) - { - if (sprite[j].cstat&16) - sprite[j].shade = (pSector->ceilingstat & 1) ? pSector->ceilingshade : pSector->floorshade; - } - } - break; - - - case SE_13_EXPLOSIVE: - if (pData[2]) - { - // t[0]: ceiling z - // t[1]: floor z - // s->owner: 1 if affect ceiling, 0 if affect floor - // t[3]: 1 if ceiling was parallaxed at premap, 0 else - - j = (SP(spriteNum)<<5)|1; - - if (pSprite->ang == 512) - { - if (pSprite->owner) - { - pSector->ceilingz = (klabs(pData[0] - pSector->ceilingz) >= j) - ? pSector->ceilingz + ksgn(pData[0] - pSector->ceilingz) * j - : pData[0]; - } - else - { - pSector->floorz = (klabs(pData[1] - pSector->floorz) >= j) - ? pSector->floorz + ksgn(pData[1] - pSector->floorz) * j - : pData[1]; - } - } - else - { - pSector->floorz = (klabs(pData[1] - pSector->floorz) >= j) - ? pSector->floorz + ksgn(pData[1] - pSector->floorz) * j - : pData[1]; - - pSector->ceilingz = /*(klabs(pData[0] - pSector->ceilingz) >= j) - ? pSector->ceilingz + ksgn(pData[0] - pSector->ceilingz) * j - : */pData[0]; - } -#ifdef YAX_ENABLE - if (pSprite->ang == 512) - { - int16_t cf=!pSprite->owner, bn=yax_getbunch(pSector-sector, cf); - int32_t jj, daz=SECTORFLD(pSector-sector,z, cf); - - if (bn >= 0) - { - for (SECTORS_OF_BUNCH(bn, cf, jj)) - { - SECTORFLD(jj,z, cf) = daz; - SECTORFLD(jj,stat, cf) &= ~(128+256 + 512+2048); - } - for (SECTORS_OF_BUNCH(bn, !cf, jj)) - { - SECTORFLD(jj,z, !cf) = daz; - SECTORFLD(jj,stat, !cf) &= ~(128+256 + 512+2048); - } - } - } -#endif - if (pData[3] == 1) - { - //Change the shades - - pData[3]++; - pSector->ceilingstat ^= 1; - - if (pSprite->ang == 512) - { - walltype *pWall = &wall[pSector->wallptr]; - - for (j = pSector->wallnum; j > 0; j--, pWall++) - pWall->shade = pSprite->shade; - - pSector->floorshade = pSprite->shade; - - if (g_player[0].ps->one_parallax_sectnum >= 0) - { - pSector->ceilingpicnum = sector[g_player[0].ps->one_parallax_sectnum].ceilingpicnum; - pSector->ceilingshade = sector[g_player[0].ps->one_parallax_sectnum].ceilingshade; - } - } - } - - if (++pData[2] > 256) - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - - if (pData[2] == 4 && pSprite->ang != 512) - for (x=0; x<7; x++) RANDOMSCRAP(pSprite, spriteNum); - break; - - - case SE_15_SLIDING_DOOR: - - if (pData[4]) - { - pSprite->xvel = 16; - - if (pData[4] == 1) //Opening - { - if (pData[3] >= (SP(spriteNum)>>3)) - { - pData[4] = 0; //Turn off the sliders - A_CallSound(pSprite->sectnum,spriteNum); - break; - } - pData[3]++; - } - else if (pData[4] == 2) - { - if (pData[3]<1) - { - pData[4] = 0; - A_CallSound(pSprite->sectnum,spriteNum); - break; - } - pData[3]--; - } - - A_MoveSector(spriteNum); - setsprite(spriteNum,(vec3_t *)pSprite); - } - break; - - case SE_16_REACTOR: //Reactor - - pData[2]+=32; - - if (pSector->floorz < pSector->ceilingz) - pSprite->shade = 0; - else if (pSector->ceilingz < pData[3]) - { - //The following code check to see if - //there is any other sprites in the sector. - //If there isn't, then kill this sectoreffector - //itself..... - - for (SPRITES_OF_SECT(pSprite->sectnum, j)) - { - if (sprite[j].picnum == TILE_REACTOR || sprite[j].picnum == TILE_REACTOR2) - break; - } - - if (j == -1) - DELETE_SPRITE_AND_CONTINUE(spriteNum); - - pSprite->shade = 1; - } - - pSector->ceilingz = (pSprite->shade) - ? pSector->ceilingz + 1024 - : pSector->ceilingz - 512; - - A_MoveSector(spriteNum); - setsprite(spriteNum,(vec3_t *)pSprite); - - break; - - case SE_17_WARP_ELEVATOR: - { - int32_t nextk; - - q = pData[0]*(SP(spriteNum)<<2); - - pSector->ceilingz += q; - pSector->floorz += q; - - for (SPRITES_OF_SECT(pSprite->sectnum, j)) - { - if (sprite[j].statnum == STAT_PLAYER && sprite[j].owner >= 0) - { - int const warpPlayer = P_Get(j); - DukePlayer_t *const pPlayer = g_player[warpPlayer].ps; - - if (numplayers < 2 && !g_netServer) - pPlayer->opos.z = pPlayer->pos.z; - - pPlayer->pos.z += q; - pPlayer->truefz += q; - pPlayer->truecz += q; - - if (g_netServer || numplayers > 1) - pPlayer->opos.z = pPlayer->pos.z; - } - - if (sprite[j].statnum != STAT_EFFECTOR) - { - actor[j].bpos.z = sprite[j].z; - sprite[j].z += q; - } - - actor[j].floorz = pSector->floorz; - actor[j].ceilingz = pSector->ceilingz; - } - - if (pData[0]) //If in motion - { - if (klabs(pSector->floorz-pData[2]) <= SP(spriteNum)) - { - G_ActivateWarpElevators(spriteNum,0); - break; - } - - // If we still see the opening, we can't yet teleport. - if (pData[0]==-1) - { - if (pSector->floorz > pData[3]) - break; - } - else if (pSector->ceilingz < pData[4]) break; - - if (pData[1] == 0) break; - pData[1] = 0; - - for (SPRITES_OF(STAT_EFFECTOR, j)) - { - if (spriteNum != j && sprite[j].lotag == SE_17_WARP_ELEVATOR) - if (pSector->hitag-pData[0] == sector[sprite[j].sectnum].hitag - && spriteHitag == sprite[j].hitag) - break; - } - - if (j == -1) break; - - for (SPRITES_OF_SECT_SAFE(pSprite->sectnum, k, nextk)) - { - if (sprite[k].statnum == STAT_PLAYER && sprite[k].owner >= 0) - { - int const warpPlayer = P_Get(k); - DukePlayer_t *const pPlayer = g_player[warpPlayer].ps; - - pPlayer->pos.x += sprite[j].x - pSprite->x; - pPlayer->pos.y += sprite[j].y - pSprite->y; - pPlayer->pos.z = sector[sprite[j].sectnum].floorz - (pSector->floorz - pPlayer->pos.z); - - actor[k].floorz = sector[sprite[j].sectnum].floorz; - actor[k].ceilingz = sector[sprite[j].sectnum].ceilingz; - *(vec2_t *)&pPlayer->opos = *(vec2_t *)pPlayer; - *(vec2_t *)&pPlayer->bobpos = *(vec2_t *)pPlayer; - pPlayer->opos.z = pPlayer->pos.z; - pPlayer->truefz = actor[k].floorz; - pPlayer->truecz = actor[k].ceilingz; - pPlayer->bobcounter = 0; - - changespritesect(k, sprite[j].sectnum); - pPlayer->cursectnum = sprite[j].sectnum; - } - else if (sprite[k].statnum != STAT_EFFECTOR) - { - sprite[k].x += sprite[j].x-pSprite->x; - sprite[k].y += sprite[j].y-pSprite->y; - sprite[k].z = sector[sprite[j].sectnum].floorz - (pSector->floorz - sprite[k].z); - - Bmemcpy(&actor[k].bpos, &sprite[k], sizeof(vec3_t)); - - changespritesect(k,sprite[j].sectnum); - setsprite(k,(vec3_t *)&sprite[k]); - - actor[k].floorz = sector[sprite[j].sectnum].floorz; - actor[k].ceilingz = sector[sprite[j].sectnum].ceilingz; - } - } - } - break; - } - - case SE_18_INCREMENTAL_SECTOR_RISE_FALL: - if (pData[0]) - { - if (pSprite->pal) - { - if (pSprite->ang == 512) - { - pSector->ceilingz -= pSector->extra; - if (pSector->ceilingz <= pData[1]) - { - pSector->ceilingz = pData[1]; - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - } - else - { - pSector->floorz += pSector->extra; - - if (!RR) - for (bssize_t SPRITES_OF_SECT(pSprite->sectnum, sectSprite)) - { - if (sprite[sectSprite].picnum == TILE_APLAYER && sprite[sectSprite].owner >= 0 && g_player[P_Get(sectSprite)].ps->on_ground == 1) - g_player[P_Get(sectSprite)].ps->pos.z += pSector->extra; - - if (sprite[sectSprite].zvel == 0 && sprite[sectSprite].statnum != STAT_EFFECTOR && sprite[sectSprite].statnum != STAT_PROJECTILE) - { - actor[sectSprite].bpos.z = sprite[sectSprite].z += pSector->extra; - actor[sectSprite].floorz = pSector->floorz; - } - } - - if (pSector->floorz >= pData[1]) - { - pSector->floorz = pData[1]; - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - } - } - else - { - if (pSprite->ang == 512) - { - pSector->ceilingz += pSector->extra; - if (pSector->ceilingz >= pSprite->z) - { - pSector->ceilingz = pSprite->z; - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - } - else - { - pSector->floorz -= pSector->extra; - - if (!RR) - for (bssize_t SPRITES_OF_SECT(pSprite->sectnum, sectSprite)) - { - if (sprite[sectSprite].picnum == TILE_APLAYER && sprite[sectSprite].owner >= 0 &&g_player[P_Get(sectSprite)].ps->on_ground == 1) - g_player[P_Get(sectSprite)].ps->pos.z -= pSector->extra; - - if (sprite[sectSprite].zvel == 0 && sprite[sectSprite].statnum != STAT_EFFECTOR && sprite[sectSprite].statnum != STAT_PROJECTILE) - { - actor[sectSprite].bpos.z = sprite[sectSprite].z -= pSector->extra; - actor[sectSprite].floorz = pSector->floorz; - } - } - - if (pSector->floorz <= pSprite->z) - { - pSector->floorz = pSprite->z; - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - } - } - - if (++pData[2] >= pSprite->hitag) - { - pData[2] = 0; - pData[0] = 0; - } - } - break; - - case SE_19_EXPLOSION_LOWERS_CEILING: //Battlestar galactia shields - - if (pData[0]) - { - if (pData[0] == 1) - { - pData[0]++; - x = pSector->wallptr; - q = x+pSector->wallnum; - - for (j=x; j= 0) - { - wall[wall[j].nextwall].overpicnum = 0; - wall[wall[j].nextwall].cstat &= (128+32+8+4+2); - } - } - } - } - - if (pSector->ceilingz < pSector->floorz) - pSector->ceilingz += SP(spriteNum); - else - { - pSector->ceilingz = pSector->floorz; - - for (SPRITES_OF(STAT_EFFECTOR, j)) - { - if (sprite[j].lotag == SE_0_ROTATING_SECTOR && sprite[j].hitag==spriteHitag) - { - sectortype *const pSector = §or[sprite[j].sectnum]; - int const ownerSector = sprite[sprite[j].owner].sectnum; - - pSector->ceilingpal = sector[ownerSector].floorpal; - pSector->floorpal = pSector->ceilingpal; - pSector->ceilingshade = sector[ownerSector].floorshade; - pSector->floorshade = pSector->ceilingshade; - - actor[sprite[j].owner].t_data[0] = 2; - } - } - - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - } - else //Not hit yet - { - if (G_FindExplosionInSector(pSprite->sectnum) >= 0) - { - P_DoQuote(QUOTE_UNLOCKED, g_player[myconnectindex].ps); - - for (SPRITES_OF(STAT_EFFECTOR, l)) - { - switch (sprite[l].lotag & 0x7fff) - { - case SE_0_ROTATING_SECTOR: - if (sprite[l].hitag == spriteHitag) - { - int const spriteOwner = sprite[l].owner; - int const sectNum = sprite[l].sectnum; - - sector[sectNum].ceilingshade = sprite[spriteOwner].shade; - sector[sectNum].floorshade = sector[sectNum].ceilingshade; - sector[sectNum].ceilingpal = sprite[spriteOwner].pal; - sector[sectNum].floorpal = sector[sectNum].ceilingpal; - } - break; - - case SE_1_PIVOT: - case SE_12_LIGHT_SWITCH: -// case SE_18_INCREMENTAL_SECTOR_RISE_FALL: - case SE_19_EXPLOSION_LOWERS_CEILING: - if (spriteHitag == sprite[l].hitag) - if (actor[l].t_data[0] == 0) - { - actor[l].t_data[0] = 1; // Shut them all on - sprite[l].owner = spriteNum; - } - - break; - } - } - } - } - - break; - - case SE_20_STRETCH_BRIDGE: //Extend-o-bridge - if (pData[0] == 0) break; - pSprite->xvel = (pData[0] == 1) ? 8 : -8; - - if (pSprite->xvel) //Moving - { - vec2_t const vect = { (pSprite->xvel * sintable[(pSprite->ang + 512) & 2047]) >> 14, - (pSprite->xvel * sintable[pSprite->ang & 2047]) >> 14 }; - - pData[3] += pSprite->xvel; - - pSprite->x += vect.x; - pSprite->y += vect.y; - - if (pData[3] <= 0 || (pData[3] >> 6) >= (SP(spriteNum) >> 6)) - { - pSprite->x -= vect.x; - pSprite->y -= vect.y; - pData[0] = 0; - A_CallSound(pSprite->sectnum, spriteNum); - break; - } - - for (bssize_t nextSprite, SPRITES_OF_SECT_SAFE(pSprite->sectnum, sectSprite, nextSprite)) - { - if (sprite[sectSprite].statnum != STAT_EFFECTOR && sprite[sectSprite].zvel == 0) - { - sprite[sectSprite].x += vect.x; - sprite[sectSprite].y += vect.y; - - setsprite(sectSprite, (vec3_t *)&sprite[sectSprite]); - - if (sector[sprite[sectSprite].sectnum].floorstat & 2 && sprite[sectSprite].statnum == STAT_ZOMBIEACTOR) - A_Fall(sectSprite); - } - } - - dragpoint((int16_t)pData[1], wall[pData[1]].x + vect.x, wall[pData[1]].y + vect.y, 0); - dragpoint((int16_t)pData[2], wall[pData[2]].x + vect.x, wall[pData[2]].y + vect.y, 0); - - for (bssize_t TRAVERSE_CONNECT(playerNum)) - { - DukePlayer_t *const pPlayer = g_player[playerNum].ps; - - if (pPlayer->cursectnum == pSprite->sectnum && pPlayer->on_ground) - { - pPlayer->pos.x += vect.x; - pPlayer->pos.y += vect.y; - - pPlayer->opos.x = pPlayer->pos.x; - pPlayer->opos.y = pPlayer->pos.y; - - pPlayer->pos.z += PHEIGHT; - setsprite(pPlayer->i, (vec3_t *)pPlayer); - pPlayer->pos.z -= PHEIGHT; - } - } - - pSector->floorxpanning -= vect.x >> 3; - pSector->floorypanning -= vect.y >> 3; - - pSector->ceilingxpanning -= vect.x >> 3; - pSector->ceilingypanning -= vect.y >> 3; - } - - break; - - case SE_21_DROP_FLOOR: // Cascading effect - { - if (pData[0] == 0) break; - - int32_t *zptr = (pSprite->ang == 1536) ? &pSector->ceilingz : &pSector->floorz; - - if (pData[0] == 1) //Decide if the s->sectnum should go up or down - { - pSprite->zvel = ksgn(pSprite->z-*zptr) * (SP(spriteNum)<<4); - pData[0]++; - } - - if (pSector->extra == 0) - { - *zptr += pSprite->zvel; - - if (klabs(*zptr-pSprite->z) < 1024) - { - *zptr = pSprite->z; - DELETE_SPRITE_AND_CONTINUE(spriteNum); //All done // SE_21_KILLIT, see sector.c - } - } - else pSector->extra--; - break; - } - - case SE_22_TEETH_DOOR: - if (pData[1]) - { - if (GetAnimationGoal(§or[pData[0]].ceilingz) >= 0) - pSector->ceilingz += pSector->extra*9; - else pData[1] = 0; - } - break; - - case 156: - if (!RRRA) break; - fallthrough__; - case SE_24_CONVEYOR: - case SE_34: - { - if (pData[4]) - break; - - vec2_t const vect = { (SP(spriteNum) * sintable[(pSprite->ang + 512) & 2047]) >> 18, - (SP(spriteNum) * sintable[pSprite->ang & 2047]) >> 18 }; - - k = 0; - - for (bssize_t nextSprite, SPRITES_OF_SECT_SAFE(pSprite->sectnum, sectSprite, nextSprite)) - { - if (sprite[sectSprite].zvel < 0) - continue; - - switch (sprite[sectSprite].statnum) - { - case STAT_MISC: - switch (DYNAMICTILEMAP(sprite[sectSprite].picnum)) - { - case PUKE__STATIC: - case FOOTPRINTS4__STATIC: - case BLOODSPLAT1__STATIC: - case BLOODSPLAT2__STATIC: - case BLOODSPLAT3__STATIC: - case BLOODSPLAT4__STATIC: - if (RR) break; - fallthrough__; - case BULLETHOLE__STATIC: - if (RR && sprite[sectSprite].picnum == TILE_BULLETHOLE) continue; - fallthrough__; - case BLOODPOOL__STATIC: - case FOOTPRINTS__STATIC: - case FOOTPRINTS2__STATIC: - case FOOTPRINTS3__STATIC: sprite[sectSprite].xrepeat = sprite[sectSprite].yrepeat = 0; continue; - - case LASERLINE__STATIC: if (RR) break; continue; - } - fallthrough__; - case STAT_STANDABLE: - if (!RR && sprite[sectSprite].picnum == TILE_TRIPBOMB) - break; - fallthrough__; - case STAT_ACTOR: - case STAT_DEFAULT: - if (sprite[sectSprite].picnum == TILE_BOLT1 - || sprite[sectSprite].picnum == TILE_BOLT1 + 1 - || sprite[sectSprite].picnum == TILE_BOLT1 + 2 - || sprite[sectSprite].picnum == TILE_BOLT1 + 3 - || (!RR && (sprite[sectSprite].picnum == TILE_SIDEBOLT1 - || sprite[sectSprite].picnum == TILE_SIDEBOLT1 + 1 - || sprite[sectSprite].picnum == TILE_SIDEBOLT1 + 2 - || sprite[sectSprite].picnum == TILE_SIDEBOLT1 + 3)) - || A_CheckSwitchTile(sectSprite)) - break; - - if (!(sprite[sectSprite].picnum >= TILE_CRANE && sprite[sectSprite].picnum <= TILE_CRANE + 3)) - { - if (sprite[sectSprite].z > actor[sectSprite].floorz - ZOFFSET2) - { - actor[sectSprite].bpos.x = sprite[sectSprite].x; - actor[sectSprite].bpos.y = sprite[sectSprite].y; - - sprite[sectSprite].x += vect.x >> (RR ? 1 : 2); - sprite[sectSprite].y += vect.y >> (RR ? 1 : 2); - - setsprite(sectSprite, (vec3_t *)&sprite[sectSprite]); - - if (sector[sprite[sectSprite].sectnum].floorstat & 2) - if (sprite[sectSprite].statnum == STAT_ZOMBIEACTOR) - A_Fall(sectSprite); - } - } - break; - } - } - - for (bssize_t TRAVERSE_CONNECT(playerNum)) - { - DukePlayer_t *const pPlayer = g_player[playerNum].ps; - - if (pPlayer->cursectnum == pSprite->sectnum && pPlayer->on_ground) - { - if (klabs(pPlayer->pos.z - pPlayer->truefz) < PHEIGHT + (9 << 8)) - { - pPlayer->fric.x += vect.x << 3; - pPlayer->fric.y += vect.y << 3; - } - } - } - if (!RRRA || spriteLotag != 156) - pSector->floorxpanning += SP(spriteNum)>>7; - - break; - } - - case SE_35: - if (pSector->ceilingz > pSprite->z) - { - for (j = 0; j < 8; j++) - { - pSprite->ang += krand2()&511; - k = A_Spawn(spriteNum, TILE_SMALLSMOKE); - sprite[k].xvel = 96+(krand2()&127); - A_SetSprite(k, CLIPMASK0); - setsprite(k, (vec3_t *) &sprite[k]); - if (rnd(16)) - A_Spawn(spriteNum, TILE_EXPLOSION2); - } - - } - switch (pData[0]) - { - case 0: - pSector->ceilingz += pSprite->yvel; - if (pSector->ceilingz > pSector->floorz) - pSector->floorz = pSector->ceilingz; - if (pSector->ceilingz > pSprite->z+ZOFFSET5) - pData[0]++; - break; - case 1: - pSector->ceilingz-=(pSprite->yvel<<2); - if (pSector->ceilingz < pData[4]) - { - pSector->ceilingz = pData[4]; - pData[0] = 0; - } - break; - } - break; - - case SE_25_PISTON: //PISTONS - if (pData[4] == 0) break; - - if (pSector->floorz <= pSector->ceilingz) - pSprite->shade = 0; - else if (pSector->ceilingz <= pData[RR?4:3]) - pSprite->shade = 1; - - if (pSprite->shade) - { - pSector->ceilingz += SP(spriteNum)<<4; - if (pSector->ceilingz > pSector->floorz) - { - pSector->ceilingz = pSector->floorz; - if (RRRA && g_pistonSound) - A_PlaySound(371, spriteNum); - } - } - else - { - pSector->ceilingz -= SP(spriteNum)<<4; - if (pSector->ceilingz < pData[RR?4:3]) - { - pSector->ceilingz = pData[RR?4:3]; - if (RRRA && g_pistonSound) - A_PlaySound(167, spriteNum); - } - } - - break; - - case SE_26: - { - int32_t p, nextj; - - pSprite->xvel = 32; - l = (pSprite->xvel*sintable[(pSprite->ang+512)&2047])>>14; - x = (pSprite->xvel*sintable[pSprite->ang&2047])>>14; - - pSprite->shade++; - if (pSprite->shade > 7) - { - pSprite->x = pData[3]; - pSprite->y = pData[4]; - pSector->floorz -= ((pSprite->zvel*pSprite->shade)-pSprite->zvel); - pSprite->shade = 0; - } - else - pSector->floorz += pSprite->zvel; - - for (SPRITES_OF_SECT_SAFE(pSprite->sectnum, j, nextj)) - { - if (sprite[j].statnum != STAT_EFFECTOR && sprite[j].statnum != STAT_PLAYER ) - { - actor[j].bpos.x = sprite[j].x; - actor[j].bpos.y = sprite[j].y; - - sprite[j].x += l; - sprite[j].y += x; - sprite[j].z += pSprite->zvel; - - setsprite(j, (vec3_t *)&sprite[j]); - } - } - - for (TRAVERSE_CONNECT(p)) - { - DukePlayer_t *const pPlayer = g_player[p].ps; - - if (pSprite->sectnum == sprite[pPlayer->i].sectnum && pPlayer->on_ground) - { - pPlayer->fric.x += l << 5; - pPlayer->fric.y += x << 5; - pPlayer->pos.z += pSprite->zvel; - } - } - - A_MoveSector(spriteNum); - setsprite(spriteNum,(vec3_t *)pSprite); - - break; - } - - case SE_27_DEMO_CAM: - { - if (ud.recstat == 0 || !cl_democams) break; - - actor[spriteNum].tempang = pSprite->ang; - - int const p = A_FindPlayer(pSprite,&x); - DukePlayer_t * const ps = g_player[p].ps; - - if (sprite[ps->i].extra > 0 && myconnectindex == screenpeek) - { - if (pData[0] < 0) - { - ud.camerasprite = spriteNum; - pData[0]++; - } - else if (ud.recstat == 2 && ps->newowner == -1) - { - if (cansee(pSprite->x,pSprite->y,pSprite->z,SECT(spriteNum),ps->pos.x,ps->pos.y,ps->pos.z,ps->cursectnum)) - { - if (x < (int32_t)((unsigned)spriteHitag)) - { - ud.camerasprite = spriteNum; - pData[0] = 999; - pSprite->ang += G_GetAngleDelta(pSprite->ang,getangle(ps->pos.x-pSprite->x,ps->pos.y-pSprite->y))>>3; - SP(spriteNum) = 100+((pSprite->z-ps->pos.z)/257); - - } - else if (pData[0] == 999) - { - if (ud.camerasprite == spriteNum) - pData[0] = 0; - else pData[0] = -10; - ud.camerasprite = spriteNum; - - } - } - else - { - pSprite->ang = getangle(ps->pos.x-pSprite->x,ps->pos.y-pSprite->y); - - if (pData[0] == 999) - { - if (ud.camerasprite == spriteNum) - pData[0] = 0; - else pData[0] = -20; - ud.camerasprite = spriteNum; - } - } - } - } - break; - } - - case SE_28_LIGHTNING: - { - if (RR) - break; - if (pData[5] > 0) - { - pData[5]--; - break; - } - - if (T1(spriteNum) == 0) - { - A_FindPlayer(pSprite,&x); - if (x > 15500) - break; - T1(spriteNum) = 1; - T2(spriteNum) = 64 + (krand2()&511); - T3(spriteNum) = 0; - } - else - { - T3(spriteNum)++; - if (T3(spriteNum) > T2(spriteNum)) - { - T1(spriteNum) = 0; - g_player[screenpeek].ps->visibility = ud.const_visibility; - break; - } - else if (T3(spriteNum) == (T2(spriteNum)>>1)) - A_PlaySound(THUNDER,spriteNum); - else if (T3(spriteNum) == (T2(spriteNum)>>3)) - A_PlaySound(LIGHTNING_SLAP,spriteNum); - else if (T3(spriteNum) == (T2(spriteNum)>>2)) - { - for (SPRITES_OF(STAT_DEFAULT, j)) - if (sprite[j].picnum == TILE_NATURALLIGHTNING && sprite[j].hitag == pSprite->hitag) - sprite[j].cstat |= 32768; - } - else if (T3(spriteNum) > (T2(spriteNum)>>3) && T3(spriteNum) < (T2(spriteNum)>>2)) - { - if (cansee(pSprite->x,pSprite->y,pSprite->z,pSprite->sectnum,g_player[screenpeek].ps->pos.x,g_player[screenpeek].ps->pos.y,g_player[screenpeek].ps->pos.z,g_player[screenpeek].ps->cursectnum)) - j = 1; - else j = 0; - - if (rnd(192) && (T3(spriteNum)&1)) - { - if (j) - g_player[screenpeek].ps->visibility = 0; - } - else if (j) - g_player[screenpeek].ps->visibility = ud.const_visibility; - - for (SPRITES_OF(STAT_DEFAULT, j)) - { - if (sprite[j].picnum == TILE_NATURALLIGHTNING && sprite[j].hitag == pSprite->hitag) - { - if (rnd(32) && (T3(spriteNum)&1)) - { - int32_t p; - DukePlayer_t *ps; - - sprite[j].cstat &= 32767; - A_Spawn(j,TILE_SMALLSMOKE); - - p = A_FindPlayer(pSprite, NULL); - ps = g_player[p].ps; - - x = ldist(&sprite[ps->i], &sprite[j]); - if (x < 768) - { - if (!A_CheckSoundPlaying(ps->i,DUKE_LONGTERM_PAIN)) - A_PlaySound(DUKE_LONGTERM_PAIN,ps->i); - A_PlaySound(SHORT_CIRCUIT,ps->i); - sprite[ps->i].extra -= 8+(krand2()&7); - - P_PalFrom(ps, 32, 16,0,0); - } - break; - } - else sprite[j].cstat |= 32768; - } - } - } - } - break; - } - - case SE_29_WAVES: - pSprite->hitag += 64; - l = mulscale12((int32_t)pSprite->yvel,sintable[pSprite->hitag&2047]); - pSector->floorz = pSprite->z + l; - break; - - case SE_31_FLOOR_RISE_FALL: // True Drop Floor - if (pData[0] == 1) - { - // Choose dir - - if (!RR && pData[3] > 0) - { - pData[3]--; - break; - } - - if (pData[2] == 1) // Retract - { - if (SA(spriteNum) != 1536) - HandleSE31(spriteNum, 1, pSprite->z, 0, pSprite->z-pSector->floorz); - else - HandleSE31(spriteNum, 1, pData[1], 0, pData[1]-pSector->floorz); - - Yax_SetBunchZs(pSector-sector, YAX_FLOOR, pSector->floorz); - - break; - } - - if ((pSprite->ang&2047) == 1536) - HandleSE31(spriteNum, 0, pSprite->z, 1, pSprite->z-pSector->floorz); - else - HandleSE31(spriteNum, 0, pData[1], 1, pData[1]-pSprite->z); - - Yax_SetBunchZs(pSector-sector, YAX_FLOOR, pSector->floorz); - } - break; - - case SE_32_CEILING_RISE_FALL: // True Drop Ceiling - if (pData[0] == 1) - { - // Choose dir - - if (pData[2] == 1) // Retract - { - if (SA(spriteNum) != 1536) - { - if (klabs(pSector->ceilingz - pSprite->z) < (SP(spriteNum)<<1)) - { - pSector->ceilingz = pSprite->z; - A_CallSound(pSprite->sectnum,spriteNum); - pData[2] = 0; - pData[0] = 0; - } - else pSector->ceilingz += ksgn(pSprite->z-pSector->ceilingz)*SP(spriteNum); - } - else - { - if (klabs(pSector->ceilingz - pData[1]) < (SP(spriteNum)<<1)) - { - pSector->ceilingz = pData[1]; - A_CallSound(pSprite->sectnum,spriteNum); - pData[2] = 0; - pData[0] = 0; - } - else pSector->ceilingz += ksgn(pData[1]-pSector->ceilingz)*SP(spriteNum); - } - - Yax_SetBunchZs(pSector-sector, YAX_CEILING, pSector->ceilingz); - - break; - } - - if ((pSprite->ang&2047) == 1536) - { - if (klabs(pSector->ceilingz-pSprite->z) < (SP(spriteNum)<<1)) - { - pData[0] = 0; - pData[2] = !pData[2]; - A_CallSound(pSprite->sectnum,spriteNum); - pSector->ceilingz = pSprite->z; - } - else pSector->ceilingz += ksgn(pSprite->z-pSector->ceilingz)*SP(spriteNum); - } - else - { - if (klabs(pSector->ceilingz-pData[1]) < (SP(spriteNum)<<1)) - { - pData[0] = 0; - pData[2] = !pData[2]; - A_CallSound(pSprite->sectnum,spriteNum); - } - else pSector->ceilingz -= ksgn(pSprite->z-pData[1])*SP(spriteNum); - } - - Yax_SetBunchZs(pSector-sector, YAX_CEILING, pSector->ceilingz); - } - break; - - case SE_33_QUAKE_DEBRIS: - if (g_earthquakeTime > 0 && (krand2()&7) == 0) - RANDOMSCRAP(pSprite, spriteNum); - break; - - case SE_36_PROJ_SHOOTER: - if (pData[0]) - { - if (pData[0] == 1) - A_Shoot(spriteNum,pSector->extra); - else if (pData[0] == GAMETICSPERSEC*5) - pData[0] = 0; - pData[0]++; - } - break; - - case 128: //SE to control glass breakage - { - walltype *pWall = &wall[pData[2]]; - - if (pWall->cstat|32) - { - pWall->cstat &= (255-32); - pWall->cstat |= 16; - if (pWall->nextwall >= 0) - { - wall[pWall->nextwall].cstat &= (255-32); - wall[pWall->nextwall].cstat |= 16; - } - } - else break; - - pWall->overpicnum++; - if (pWall->nextwall >= 0) - wall[pWall->nextwall].overpicnum++; - - if (pData[0] < pData[1]) pData[0]++; - else - { - pWall->cstat &= (128+32+8+4+2); - if (pWall->nextwall >= 0) - wall[pWall->nextwall].cstat &= (128+32+8+4+2); - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - } - break; - - case SE_130: - if (pData[0] > 80) - { - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - else pData[0]++; - - x = pSector->floorz-pSector->ceilingz; - - if (rnd(64)) - { - k = A_Spawn(spriteNum,TILE_EXPLOSION2); - sprite[k].xrepeat = sprite[k].yrepeat = 2+(krand2()&7); - sprite[k].z = pSector->floorz-(krand2()%x); - sprite[k].ang += 256-(krand2()%511); - sprite[k].xvel = krand2()&127; - A_SetSprite(k,CLIPMASK0); - } - break; - - case SE_131: - if (pData[0] > 40) - { - DELETE_SPRITE_AND_CONTINUE(spriteNum); - } - else pData[0]++; - - x = pSector->floorz-pSector->ceilingz; - - if (rnd(32)) - { - k = A_Spawn(spriteNum,TILE_EXPLOSION2); - sprite[k].xrepeat = sprite[k].yrepeat = 2+(krand2()&3); - sprite[k].z = pSector->floorz-(krand2()%x); - sprite[k].ang += 256-(krand2()%511); - sprite[k].xvel = krand2()&127; - A_SetSprite(k,CLIPMASK0); - } - break; - - case SE_49_POINT_LIGHT: - case SE_50_SPOT_LIGHT: - changespritestat(spriteNum, STAT_LIGHT); - break; - } -next_sprite: - spriteNum = nextSprite; - } - - //Sloped sin-wave floors! - for (SPRITES_OF(STAT_EFFECTOR, spriteNum)) - { - const spritetype *s = &sprite[spriteNum]; - - if (s->lotag == SE_29_WAVES) - { - usectortype const *const sc = (usectortype *)§or[s->sectnum]; - - if (sc->wallnum == 4) - { - walltype *const pWall = &wall[sc->wallptr+2]; - if (pWall->nextsector >= 0) - alignflorslope(s->sectnum, pWall->x,pWall->y, sector[pWall->nextsector].floorz); - } - } - } -} static void G_DoEffectorLights(void) // STATNUM 14 { @@ -3312,6 +850,7 @@ void moveweapons_d(); void movetransports_d(void); void moveactors_d(); void moveexplosions_d(); +void moveeffectors_d(); void movefta_r(void); void moveplayers(); @@ -3323,6 +862,7 @@ void movetransports_r(void); void moveactors_r(); void thunder(); void moveexplosions_r(); +void moveeffectors_r(); void G_MoveWorld_d(void) { @@ -3346,7 +886,7 @@ void G_MoveWorld_d(void) // XXX: Has to be before effectors, in particular movers? // TODO: lights in moving sectors ought to be interpolated G_DoEffectorLights(); - G_MoveEffectors(); //ST 3 + moveeffectors_d(); //ST 3 movestandables_d(); //ST 6 G_RefreshLights(); @@ -3394,7 +934,7 @@ void G_MoveWorld_r(void) G_DoEffectorLights(); if (!DEER) { - G_MoveEffectors(); //ST 3 + moveeffectors_r(); //ST 3 movestandables_r(); //ST 6 } diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index be04944e1..e5145bfbb 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -1688,7 +1688,7 @@ default_case: if (!RRRA) goto default_case; pSprite->xrepeat = 0; pSprite->yrepeat = 0; - g_pistonSound = 1; + pistonsound = 1; break; case RRTILE8165__STATICRR: if (!RRRA) goto default_case; @@ -4009,7 +4009,7 @@ rr_badguy: fallthrough__; case SE_0_ROTATING_SECTOR: case SE_2_EARTHQUAKE: // Earthquakemakers - case SE_5: // Boss Creature + case SE_5_BOSS: // Boss Creature case SE_6_SUBWAY: // Subway case SE_14_SUBWAY_CAR: // Caboos case SE_15_SLIDING_DOOR: // Subwaytype sliding door @@ -4070,7 +4070,7 @@ rr_badguy: } } - if (pSprite->lotag == SE_5 || pSprite->lotag == SE_30_TWO_WAY_TRAIN || + if (pSprite->lotag == SE_5_BOSS || pSprite->lotag == SE_30_TWO_WAY_TRAIN || pSprite->lotag == SE_6_SUBWAY || pSprite->lotag == SE_14_SUBWAY_CAR) { #ifdef YAX_ENABLE @@ -4176,7 +4176,7 @@ rr_badguy: fallthrough__; case SE_0_ROTATING_SECTOR: case SE_1_PIVOT: - case SE_5: + case SE_5_BOSS: case SE_11_SWINGING_DOOR: case SE_15_SLIDING_DOOR: case SE_16_REACTOR: diff --git a/source/games/duke/src/game.h b/source/games/duke/src/game.h index 5e24ada57..46db388fb 100644 --- a/source/games/duke/src/game.h +++ b/source/games/duke/src/game.h @@ -339,7 +339,7 @@ enum SE_2_EARTHQUAKE = 2, SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT = 3, SE_4_RANDOM_LIGHTS = 4, - SE_5 = 5, + SE_5_BOSS = 5, SE_6_SUBWAY = 6, // ^^ potentially incomplete substitution in code // vv almost surely complete substitution @@ -373,6 +373,8 @@ enum SE_34 = 34, // XXX SE_35 = 35, // XXX SE_36_PROJ_SHOOTER = 36, + SE_47_LIGHT_SWITCH = 47, + SE_48_LIGHT_SWITCH = 48, SE_49_POINT_LIGHT = 49, SE_50_SPOT_LIGHT = 50, SE_130 = 130, diff --git a/source/games/duke/src/global.h b/source/games/duke/src/global.h index 2e91f9131..cde7da577 100644 --- a/source/games/duke/src/global.h +++ b/source/games/duke/src/global.h @@ -162,10 +162,14 @@ G_EXTERN int32_t g_chickenPlant; #define chickenplant g_chickenPlant G_EXTERN int32_t g_thunderOn; G_EXTERN int32_t g_ufoSpawn; +#define ufospawn g_ufoSpawn G_EXTERN int32_t g_ufoCnt; +#define ufocnt g_ufoCnt G_EXTERN int32_t g_hulkSpawn; +#define hulkspawn g_hulkSpawn G_EXTERN int32_t g_vixenLevel; G_EXTERN int32_t g_lastLevel; +#define lastlevel g_lastLevel G_EXTERN int32_t g_turdLevel; @@ -207,7 +211,7 @@ G_EXTERN msy_ msy; G_EXTERN int32_t g_windTime, g_windDir; G_EXTERN int16_t g_fakeBubbaCnt, g_mamaSpawnCnt, g_banjoSong, g_bellTime, g_bellSprite; G_EXTERN uint8_t g_spriteExtra[MAXSPRITES], g_sectorExtra[MAXSECTORS]; -G_EXTERN uint8_t enemysizecheat, ufospawnsminion, g_pistonSound, g_chickenWeaponTimer, g_RAendLevel, g_RAendEpisode, g_fogType; +G_EXTERN uint8_t enemysizecheat, ufospawnsminion, pistonsound, g_chickenWeaponTimer, g_RAendLevel, g_RAendEpisode, g_fogType; G_EXTERN int32_t g_cdTrack; #define raat607 enemysizecheat // only as a reminder @@ -223,6 +227,7 @@ playerdata_t *const g_player = &g_player_s[1]; extern playerdata_t *const g_player; #endif G_EXTERN playerspawn_t g_playerSpawnPoints[MAXPLAYERS]; +#define po g_playerSpawnPoints G_EXTERN input_t inputfifo[MOVEFIFOSIZ][MAXPLAYERS]; #pragma pack(pop) @@ -271,7 +276,16 @@ extern int16_t g_blimpSpawnItems[15]; extern int32_t g_gametypeFlags[MAXGAMETYPES]; extern const char *s_buildDate; -#endif +#endif + +inline void clearfriction() +{ + for (int playerNum = 0; playerNum != -1; playerNum = connectpoint2[playerNum]) + { + vec2_t& fric = g_player[playerNum].ps->fric; + fric.x = fric.y = 0; + } +} enum { diff --git a/source/games/duke/src/player.h b/source/games/duke/src/player.h index 40db7a0b9..6b44e782e 100644 --- a/source/games/duke/src/player.h +++ b/source/games/duke/src/player.h @@ -107,8 +107,17 @@ enum playeraction_t { }; typedef struct { - vec3_t pos; - int16_t ang, sect; + union + { + vec3_t pos; + struct { int ox, oy, oz; }; + }; + int16_t ang; + union + { + int16_t sect; + int16_t os; + }; } playerspawn_t; typedef struct { @@ -166,6 +175,7 @@ typedef struct player_struct { int getang() { return q16ang >> FRACBITS; } int getoang() { return oq16ang >> FRACBITS; } void setang(int v) { q16ang = v << FRACBITS; } + void addang(int v) { q16ang = (q16ang + (v << FRACBITS)) & ((2048 << FRACBITS)-1); } void setoang(int v) { oq16ang = v << FRACBITS; } void addhoriz(int v) { q16horiz += (v << FRACBITS); } int gethoriz() { return q16horiz >> FRACBITS; } diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index 5e22fdf0e..7179efb73 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -1276,7 +1276,7 @@ static void prelevel(char g) G_SetFog(0); g_fogType = 0; ufospawnsminion = 0; - g_pistonSound = 0; + pistonsound = 0; enemysizecheat = 0; g_player[myconnectindex].ps->level_end_timer = 0; g_mamaSpawnCnt = 15; diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index 7d0777648..cecbef932 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -117,7 +117,7 @@ void G_ResetInterpolations(void) G_SetInterpolation(§or[sprite[k].sectnum].ceilingz); break; case SE_0_ROTATING_SECTOR: - case SE_5: + case SE_5_BOSS: case SE_6_SUBWAY: case SE_11_SWINGING_DOOR: case SE_14_SUBWAY_CAR: @@ -931,7 +931,7 @@ static const dataspec_t svgm_anmisc[] = { 0, &enemysizecheat, sizeof(enemysizecheat), 1 }, { 0, &ufospawnsminion, sizeof(ufospawnsminion), 1 }, - { 0, &g_pistonSound, sizeof(g_pistonSound), 1 }, + { 0, &pistonsound, sizeof(pistonsound), 1 }, { 0, &g_chickenWeaponTimer, sizeof(g_chickenWeaponTimer), 1 }, { 0, &g_RAendLevel, sizeof(g_RAendLevel), 1 }, { 0, &g_RAendEpisode, sizeof(g_RAendEpisode), 1 }, diff --git a/source/games/duke/src/sector.cpp b/source/games/duke/src/sector.cpp index f0f7db29f..873884681 100644 --- a/source/games/duke/src/sector.cpp +++ b/source/games/duke/src/sector.cpp @@ -3860,7 +3860,7 @@ CHECKINV1: if (weaponNum == HANDBOMB_WEAPON && pPlayer->ammo_amount[HANDBOMB_WEAPON] == 0) { - int spriteNum = headspritestat[1]; + int spriteNum = headspritestat[STAT_ACTOR]; while (spriteNum >= 0) { if (sprite[spriteNum].picnum == TILE_HEAVYHBOMB && sprite[spriteNum].owner == pPlayer->i) diff --git a/source/games/duke/src/sector.h b/source/games/duke/src/sector.h index 1ec4a0063..3c95749bd 100644 --- a/source/games/duke/src/sector.h +++ b/source/games/duke/src/sector.h @@ -104,9 +104,17 @@ typedef struct { void G_ActivateBySector(int sect,int spriteNum); +inline void activatebysector(int s, int sn) +{ + G_ActivateBySector(s, sn); +} int S_FindMusicSFX(int sectNum, int *sndptr); void A_CallSound2(int soundNum, int playerNum); int A_CallSound(int sectNum,int spriteNum); +inline int callsound(int s, int sp) +{ + return A_CallSound(s, sp); +} int A_CheckHitSprite(int spriteNum,int16_t *hitSprite); inline int hitasprite(int s, int16_t* h) { @@ -134,6 +142,10 @@ int CheckBlockDoorTile(int tileNum); void G_AnimateCamSprite(int smoothRatio); void G_AnimateWalls(void); int G_ActivateWarpElevators(int s,int warpDir); +inline int activatewarpelevators(int s, int w) +{ + return G_ActivateWarpElevators(s, w); +} int G_CheckActivatorMotion(int lotag); inline int check_activator_motion(int lotag) { diff --git a/source/games/duke/src/sounds.h b/source/games/duke/src/sounds.h index 5aed76d65..0c0de2a77 100644 --- a/source/games/duke/src/sounds.h +++ b/source/games/duke/src/sounds.h @@ -74,6 +74,10 @@ inline int sound(int num) } int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos, int channel = CHAN_AUTO, EChanFlags flags = 0); void S_StopEnvSound(int sndNum,int sprNum, int flags = -1); +inline void stopsound(int snd) +{ + S_StopEnvSound(snd, -1); +} void S_Update(void); void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset); int S_GetUserFlags(int sndnum);