diff --git a/source/games/duke/CMakeLists.txt b/source/games/duke/CMakeLists.txt index 4c760d937..1234aa669 100644 --- a/source/games/duke/CMakeLists.txt +++ b/source/games/duke/CMakeLists.txt @@ -1,7 +1,9 @@ set( PCH_SOURCES src/actors.cpp - src/actors_e.cpp + src/actors_r.cpp + src/actors_d.cpp + src/e_actors.cpp src/anim.cpp src/cheats.cpp src/cmdline.cpp diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp new file mode 100644 index 000000000..2d0f547d0 --- /dev/null +++ b/source/games/duke/src/actors_d.cpp @@ -0,0 +1,3667 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment +Copyright (C) 2000, 2003 - Matt Saettler (EDuke Enhancements) +Copyright (C) 2017-2019 - Nuke.YKT +Copyright (C) 2020 - Christoph Oelckers + +This file is part of Enhanced Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms + +EDuke enhancements integrated: 04/13/2003 - Matt Saettler + +Note: EDuke source was in transition. Changes are in-progress in the +source as it is released. + +This file is a combination of code from the following sources: +- EDuke 2 by Matt Saettler +- JFDuke by Jonathon Fowler (jf@jonof.id.au), +- DukeGDX and RedneckGDX by Alexander Makarov-[M210] (m210-2007@mail.ru) +- Redneck Rampage reconstructed source by Nuke.YKT + +*/ +//------------------------------------------------------------------------- + +#include "ns.h" +#include "global.h" +#include "names.h" + +BEGIN_DUKE_NS + +struct FireProj +{ + int x, y, z; + int xv, yv, zv; +}; + +static TMap fire; + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +bool ceilingspace(int sectnum) +{ + if ((sector[sectnum].ceilingstat & 1) && sector[sectnum].ceilingpal == 0) + { + switch (sector[sectnum].ceilingpicnum) + { + case MOONSKY1: + case BIGORBIT1: + return !isRR(); + + case RR_MOONSKY1: + case RR_BIGORBIT1: + return isRR(); + } + } + return 0; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +bool floorspace(int sectnum) +{ + if ((sector[sectnum].floorstat & 1) && sector[sectnum].ceilingpal == 0) + { + switch (sector[sectnum].floorpicnum) + { + case MOONSKY1: + case BIGORBIT1: + return !isRR(); + + case RR_MOONSKY1: + case RR_BIGORBIT1: + return !!isRR(); + } + } + return 0; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void addammo(short weapon, struct player_struct* p, short amount) +{ + p->ammo_amount[weapon] += amount; + + if (p->ammo_amount[weapon] > max_ammo_amount[weapon]) + p->ammo_amount[weapon] = max_ammo_amount[weapon]; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void addweapon(struct player_struct* p, int weapon) +{ + short cw = p->curr_weapon; + if (p->OnMotorcycle || p->OnBoat) + { + p->gotweapon.Set(weapon); + if (weapon == SHRINKER_WEAPON) + { + p->gotweapon.Set(GROW_WEAPON); + p->ammo_amount[GROW_WEAPON] = 1; + } + else if (weapon == RPG_WEAPON) + { + p->gotweapon.Set(RA16_WEAPON); + } + else if (weapon == RA15_WEAPON) + { + p->ammo_amount[RA15_WEAPON] = 1; + } + return; + } + + if (p->gotweapon[weapon] == 0) + { + p->gotweapon.Set(weapon); + if (weapon == SHRINKER_WEAPON) + { + p->gotweapon.Set(GROW_WEAPON); + if (isRRRA()) p->ammo_amount[GROW_WEAPON] = 1; + } + if (isRRRA()) + { + if (weapon == RPG_WEAPON) + { + p->gotweapon.Set(RA16_WEAPON); + } + if (weapon == RA15_WEAPON) + { + p->ammo_amount[RA15_WEAPON] = 50; + } + } + + if (!isRR() || weapon != HANDBOMB_WEAPON) + cw = weapon; + } + else + cw = weapon; + + if (isRR() && weapon == HANDBOMB_WEAPON) + p->last_weapon = -1; + + p->random_club_frame = 0; + + if (p->holster_weapon == 0) + { + p->weapon_pos = -1; + p->last_weapon = p->curr_weapon; + } + else + { + p->weapon_pos = 10; + p->holster_weapon = 0; + p->last_weapon = -1; + } + + p->kickback_pic = 0; +#ifdef EDUKE + if (p->curr_weapon != cw) + { + short snum; + snum = sprite[p->i].yvel; + + SetGameVarID(g_iWeaponVarID, cw, p->i, snum); + if (p->curr_weapon >= 0) + { + SetGameVarID(g_iWorksLikeVarID, aplWeaponWorksLike[weapon][snum], p->i, snum); + } + else + { + SetGameVarID(g_iWorksLikeVarID, -1, p->i, snum); + } + SetGameVarID(g_iReturnVarID, 0, -1, snum); + OnEvent(EVENT_CHANGEWEAPON, p->i, snum, -1); + if (GetGameVarID(g_iReturnVarID, -1, snum) == 0) + { + p->curr_weapon = cw; + } + } +#else + p->curr_weapon = cw; +#endif + + switch (weapon) + { + case RA15_WEAPON: + case KNEE_WEAPON: + case TRIPBOMB_WEAPON: + case HANDREMOTE_WEAPON: + case HANDBOMB_WEAPON: + break; + case SHOTGUN_WEAPON: + spritesound(SHOTGUN_COCK, p->i); + break; + case PISTOL_WEAPON: + spritesound(INSERT_CLIP, p->i); + break; + default: + spritesound(SELECT_WEAPON, p->i); + break; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void checkavailinven(struct player_struct* p) +{ + + if (p->firstaid_amount > 0) + p->inven_icon = ICON_FIRSTAID; + else if (p->steroids_amount > 0) + p->inven_icon = ICON_STEROIDS; + else if (p->holoduke_amount > 0) + p->inven_icon = ICON_HOLODUKE; + else if (p->jetpack_amount > 0) + p->inven_icon = ICON_JETPACK; + else if (p->heat_amount > 0) + p->inven_icon = ICON_HEATS; + else if (p->scuba_amount > 0) + p->inven_icon = ICON_SCUBA; + else if (p->boot_amount > 0) + p->inven_icon = ICON_BOOTS; + else p->inven_icon = ICON_NONE; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void checkavailweapon(struct player_struct* p) +{ + short i, snum; + int weap; + + if (p->wantweaponfire >= 0) + { + weap = p->wantweaponfire; + p->wantweaponfire = -1; + + if (weap == p->curr_weapon) return; + else if (p->gotweapon[weap] && p->ammo_amount[weap] > 0) + { + addweapon(p, weap); + return; + } + } + + weap = p->curr_weapon; + if (p->gotweapon[weap] && p->ammo_amount[weap] > 0) + return; + + snum = sprite[p->i].yvel; + + // Note: RedNukem has this restriction, but the original source and RedneckGDX do not. +#if 1 // TRANSITIONAL + int max = ((isRR()) ? DEVISTATOR_WEAPON : FREEZE_WEAPON); +#else + int max = FREEZE_WEAPON; +#endif + for (i = 0; i < 10; i++) + { + weap = ud.wchoice[snum][i]; + if ((g_gameType & GAMEFLAG_SHAREWARE) && weap > 6) continue; + + if (weap == 0) weap = max; + else weap--; + + if (weap == KNEE_WEAPON || (p->gotweapon[weap] && p->ammo_amount[weap] > 0)) + break; + } + + if (i == HANDREMOTE_WEAPON) weap = KNEE_WEAPON; + + // Found the weapon + + p->last_weapon = p->curr_weapon; + p->random_club_frame = 0; + p->curr_weapon = weap; + if (isWW2GI()) + { + SetGameVarID(g_iWeaponVarID, p->curr_weapon, p->i, snum); + if (p->curr_weapon >= 0) + { + SetGameVarID(g_iWorksLikeVarID, aplWeaponWorksLike[p->curr_weapon][snum], p->i, snum); + } + else + { + SetGameVarID(g_iWorksLikeVarID, -1, p->i, snum); + } + OnEvent(EVENT_CHANGEWEAPON, p->i, snum, -1); + } + + p->kickback_pic = 0; + if (p->holster_weapon == 1) + { + p->holster_weapon = 0; + p->weapon_pos = 10; + } + else p->weapon_pos = -1; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +bool ifsquished(int i, int p) +{ + if (isRR()) return false; // this function is a no-op in RR's source. + + bool squishme = false; + if (sprite[i].picnum == TILE_APLAYER && ud.clipping) + return false; + + auto& sc = sector[sprite[i].sectnum]; + int floorceildist = sc.floorz - sc.ceilingz; + + if (sc.lotag != ST_23_SWINGING_DOOR) + { + if (sprite[i].pal == 1) + squishme = floorceildist < (32 << 8) && (sc.lotag & 32768) == 0; + else + squishme = floorceildist < (12 << 8); + } + + if (squishme) + { + FTA(QUOTE_SQUISHED, &ps[p]); + + if (badguy(&sprite[i])) + sprite[i].xvel = 0; + + if (sprite[i].pal == 1) + { + hittype[i].picnum = SHOTSPARK1; + hittype[i].extra = 1; + return false; + } + + return true; + } + return false; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void clearcamera(player_struct* ps) +{ + ps->newowner = -1; + ps->posx = ps->oposx; + ps->posy = ps->oposy; + ps->posz = ps->oposz; + ps->q16ang = ps->oq16ang; + updatesector(ps->posx, ps->posy, &ps->cursectnum); + setpal(ps); + + int k = headspritestat[1]; + while (k >= 0) + { + if (sprite[k].picnum == CAMERA1) + sprite[k].yvel = 0; + k = nextspritestat[k]; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void hitradius(short i, int r, int hp1, int hp2, int hp3, int hp4) +{ + spritetype* s, * sj; + walltype* wal; + int d, q, x1, y1; + int sectcnt, sectend, dasect, startwall, endwall, nextsect; + short j, p, x, nextj, sect; + static const uint8_t statlist[] = { STAT_DEFAULT, STAT_ACTOR, STAT_STANDABLE, STAT_PLAYER, STAT_FALLER, STAT_ZOMBIEACTOR, STAT_MISC }; + short tempshort[MAXSECTORS]; // originally hijacked a global buffer which is bad. Q: How many do we really need? RedNukem says 64. + + s = &sprite[i]; + + if (s->xrepeat < 11) + { + if (!isRR()) + { + if (s->picnum == RPG) goto SKIPWALLCHECK; + } + else + { + if (s->picnum == RR_CROSSBOW || ((isRRRA()) && s->picnum == RR_CHIKENCROSSBOW)) goto SKIPWALLCHECK; + } + } + + if ((isRR()) || s->picnum != SHRINKSPARK) + { + tempshort[0] = s->sectnum; + dasect = s->sectnum; + sectcnt = 0; sectend = 1; + + do + { + dasect = tempshort[sectcnt++]; + if (((sector[dasect].ceilingz - s->z) >> 8) < r) + { + d = abs(wall[sector[dasect].wallptr].x - s->x) + abs(wall[sector[dasect].wallptr].y - s->y); + if (d < r) + checkhitceiling(dasect); + else + { + // ouch... + d = abs(wall[wall[wall[sector[dasect].wallptr].point2].point2].x - s->x) + abs(wall[wall[wall[sector[dasect].wallptr].point2].point2].y - s->y); + if (d < r) + checkhitceiling(dasect); + } + } + + startwall = sector[dasect].wallptr; + endwall = startwall + sector[dasect].wallnum; + for (x = startwall, wal = &wall[startwall]; x < endwall; x++, wal++) + if ((abs(wal->x - s->x) + abs(wal->y - s->y)) < r) + { + nextsect = wal->nextsector; + if (nextsect >= 0) + { + for (dasect = sectend - 1; dasect >= 0; dasect--) + if (tempshort[dasect] == nextsect) break; + if (dasect < 0) tempshort[sectend++] = nextsect; + } + x1 = (((wal->x + wall[wal->point2].x) >> 1) + s->x) >> 1; + y1 = (((wal->y + wall[wal->point2].y) >> 1) + s->y) >> 1; + updatesector(x1, y1, §); + if (sect >= 0 && cansee(x1, y1, s->z, sect, s->x, s->y, s->z, s->sectnum)) + checkhitwall(i, x, wal->x, wal->y, s->z, s->picnum); + } + } while (sectcnt < sectend); + } + +SKIPWALLCHECK: + + int val = (isRR()) ? 24 : 16; + q = -(val << 8) + (krand() & ((32 << 8) - 1)); + + for (x = 0; x < 7; x++) + { + j = headspritestat[statlist[x]]; + while (j >= 0) + { + nextj = nextspritestat[j]; + sj = &sprite[j]; + + if (isWorldTour()) + { + if (sprite[s->owner].picnum == APLAYER && sj->picnum == APLAYER && ud.coop != 0 && ud.ffire == 0 && s->owner != j) + continue; + + if (s->picnum == FLAMETHROWERFLAME && ((sprite[s->owner].picnum == FIREFLY && sj->picnum == FIREFLY) || (sprite[s->owner].picnum == BOSS5 && sj->picnum == BOSS5))) + continue; + } + + if (x == 0 || x >= 5 || AFLAMABLE(sj->picnum)) + { + if ((!isRR() && s->picnum != SHRINKSPARK) || (sj->cstat & 257)) + if (dist(s, sj) < r) + { + if (badguy(sj) && !cansee(sj->x, sj->y, sj->z + q, sj->sectnum, s->x, s->y, s->z + q, s->sectnum)) + goto BOLT; + checkhitsprite(j, i); + } + } + else if (!isRR()) + { + if (sj->extra >= 0 && sj != s && (sj->picnum == TRIPBOMB || badguy(sj) || sj->picnum == QUEBALL || sj->picnum == STRIPEBALL || (sj->cstat & 257) || sj->picnum == DUKELYINGDEAD)) + { + if (s->picnum == SHRINKSPARK && sj->picnum != SHARK && (j == s->owner || sj->xrepeat < 24)) + { + j = nextj; + continue; + } + if (s->picnum == MORTER && j == s->owner) + { + j = nextj; + continue; + } + + if (sj->picnum == APLAYER) sj->z -= PHEIGHT; + d = dist(s, sj); + if (sj->picnum == APLAYER) sj->z += PHEIGHT; + + if (d < r && cansee(sj->x, sj->y, sj->z - (8 << 8), sj->sectnum, s->x, s->y, s->z - (12 << 8), s->sectnum)) + { + hittype[j].ang = getangle(sj->x - s->x, sj->y - s->y); + + if (s->picnum == RPG && sj->extra > 0) + hittype[j].picnum = RPG; + else if (!isWorldTour()) + { + if (s->picnum == SHRINKSPARK) + hittype[j].picnum = SHRINKSPARK; + else hittype[j].picnum = RADIUSEXPLOSION; + } + else + { + if (s->picnum == SHRINKSPARK || s->picnum == FLAMETHROWERFLAME) + hittype[j].picnum = s->picnum; + else if (s->picnum != FIREBALL || sprite[s->owner].picnum != APLAYER) + { + if (s->picnum == LAVAPOOL) + hittype[j].picnum = FLAMETHROWERFLAME; + else + hittype[j].picnum = RADIUSEXPLOSION; + } + else + hittype[j].picnum = FLAMETHROWERFLAME; + } + + if (s->picnum != SHRINKSPARK && (!isWorldTour() && s->picnum != LAVAPOOL)) + { + if (d < r / 3) + { + if (hp4 == hp3) hp4++; + hittype[j].extra = hp3 + (krand() % (hp4 - hp3)); + } + else if (d < 2 * r / 3) + { + if (hp3 == hp2) hp3++; + hittype[j].extra = hp2 + (krand() % (hp3 - hp2)); + } + else if (d < r) + { + if (hp2 == hp1) hp2++; + hittype[j].extra = hp1 + (krand() % (hp2 - hp1)); + } + + if (sprite[j].picnum != TANK && sprite[j].picnum != ROTATEGUN && sprite[j].picnum != RECON && sprite[j].picnum != BOSS1 && sprite[j].picnum != BOSS2 && sprite[j].picnum != BOSS3 && sprite[j].picnum != BOSS4) + { + if (sj->xvel < 0) sj->xvel = 0; + sj->xvel += (s->extra << 2); + } + + if (sj->picnum == PODFEM1 || sj->picnum == FEM1 || + sj->picnum == FEM2 || sj->picnum == FEM3 || + sj->picnum == FEM4 || sj->picnum == FEM5 || + sj->picnum == FEM6 || sj->picnum == FEM7 || + sj->picnum == FEM8 || sj->picnum == FEM9 || + sj->picnum == FEM10 || sj->picnum == STATUE || + sj->picnum == STATUEFLASH || sj->picnum == SPACEMARINE || sj->picnum == QUEBALL || sj->picnum == STRIPEBALL) + checkhitsprite(j, i); + } + else if (s->extra == 0) hittype[j].extra = 0; + + if (sj->picnum != RADIUSEXPLOSION && + s->owner >= 0 && sprite[s->owner].statnum < MAXSTATUS) + { + if (sj->picnum == APLAYER) + { + p = sj->yvel; + + if (isWorldTour() && hittype[j].picnum == FLAMETHROWERFLAME && sprite[s->owner].picnum == APLAYER) + { + ps[p].numloogs = -1 - s->yvel; + } + + if (ps[p].newowner >= 0) + { + clearcamera(&ps[p]); + } + } + hittype[j].owner = s->owner; + } + } + } + } + else + { + if (sj->extra >= 0 && sj != s && (badguy(sj) || sj->picnum == RR_QUEBALL || sj->picnum == RR_3440 || sj->picnum == RR_STRIPEBALL || (sj->cstat & 257) || sj->picnum == RR_LNRDLYINGDEAD)) + { + if (s->picnum == RR_MORTER && j == s->owner) + { + j = nextj; + continue; + } + if ((isRRRA()) && s->picnum == RR_CHEERBOMB && j == s->owner) + { + j = nextj; + continue; + } + + if (sj->picnum == APLAYER) sj->z -= PHEIGHT; + d = dist(s, sj); + if (sj->picnum == APLAYER) sj->z += PHEIGHT; + + if (d < r && cansee(sj->x, sj->y, sj->z - (8 << 8), sj->sectnum, s->x, s->y, s->z - (12 << 8), s->sectnum)) + { + if ((isRRRA()) && sprite[j].picnum == RR_MINION && sprite[j].pal == 19) + { + j = nextj; + continue; + } + + hittype[j].ang = getangle(sj->x - s->x, sj->y - s->y); + + if (s->picnum == RR_CROSSBOW && sj->extra > 0) + hittype[j].picnum = RR_CROSSBOW; + else if ((isRRRA()) && s->picnum == RR_CHIKENCROSSBOW && sj->extra > 0) + hittype[j].picnum = RR_CROSSBOW; + else + hittype[j].picnum = RR_RADIUSEXPLOSION; + + if (d < r / 3) + { + if (hp4 == hp3) hp4++; + hittype[j].extra = hp3 + (krand() % (hp4 - hp3)); + } + else if (d < 2 * r / 3) + { + if (hp3 == hp2) hp3++; + hittype[j].extra = hp2 + (krand() % (hp3 - hp2)); + } + else if (d < r) + { + if (hp2 == hp1) hp2++; + hittype[j].extra = hp1 + (krand() % (hp2 - hp1)); + } + + int pic = sprite[j].picnum; + if ((isRRRA())? + (pic != RR_HULK && pic != RR_MAMAJACKOLOPE && pic != RR_GUITARBILLY && pic != RR_BANJOCOOTER && pic != RR_MAMACLOUD) : + (pic != RR_HULK && pic != RR_SBMOVE)) + { + if (sprite[j].xvel < 0) sprite[j].xvel = 0; + sprite[j].xvel += (sprite[j].extra << 2); + } + + if (sj->picnum == RR_STATUEFLASH || sj->picnum == RR_QUEBALL || + sj->picnum == RR_STRIPEBALL || sj->picnum == RR_3440) + checkhitsprite(j, i); + + if (sprite[j].picnum != RR_RADIUSEXPLOSION && + s->owner >= 0 && sprite[s->owner].statnum < MAXSTATUS) + { + if (sprite[j].picnum == APLAYER) + { + p = sprite[j].yvel; + if (ps[p].newowner >= 0) + { + clearcamera(&ps[p]); + } + } + hittype[j].owner = s->owner; + } + } + } + } + BOLT: + j = nextj; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +int movesprite(short spritenum, int xchange, int ychange, int zchange, unsigned int cliptype) +{ + int daz, h, oldx, oldy; + short retval, dasectnum, cd; + char bg; + + bg = badguy(&sprite[spritenum]); + + if (sprite[spritenum].statnum == 5 || (bg && sprite[spritenum].xrepeat < 4)) + { + sprite[spritenum].x += (xchange * TICSPERFRAME) >> 2; + sprite[spritenum].y += (ychange * TICSPERFRAME) >> 2; + sprite[spritenum].z += (zchange * TICSPERFRAME) >> 2; + if (bg) + setsprite(spritenum, sprite[spritenum].x, sprite[spritenum].y, sprite[spritenum].z); + return 0; + } + + dasectnum = sprite[spritenum].sectnum; + + daz = sprite[spritenum].z; + h = ((tilesiz[sprite[spritenum].picnum].y * sprite[spritenum].yrepeat) << 1); + daz -= h; + + if (bg) + { + oldx = sprite[spritenum].x; + oldy = sprite[spritenum].y; + + if (sprite[spritenum].xrepeat > 60) + retval = clipmove(&sprite[spritenum].x, &sprite[spritenum].y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 1024L, (4 << 8), (4 << 8), cliptype); + else + { + if (isRR()) + cd = 192; + else if (sprite[spritenum].picnum == LIZMAN) + cd = 292; +#if 0 // TRANSITIONAL the needed infrastructure for this is too different for now + else if ((actortype[sprite[spritenum].picnum] & 3)) +#else + else if (A_CheckSpriteFlags(spritenum, SFLAG_BADGUY)) +#endif + cd = sprite[spritenum].clipdist << 2; + else + cd = 192; + + retval = clipmove(&sprite[spritenum].x, &sprite[spritenum].y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), cd, (4 << 8), (4 << 8), cliptype); + } + + bool rr = (isRR()); + // conditional code from hell... + if (dasectnum < 0 || (dasectnum >= 0 && + ((hittype[spritenum].actorstayput >= 0 && hittype[spritenum].actorstayput != dasectnum) || + (!rr && + ( + ((sprite[spritenum].picnum == BOSS2) && sprite[spritenum].pal == 0 && sector[dasectnum].lotag != 3) || + ((sprite[spritenum].picnum == BOSS1 || sprite[spritenum].picnum == BOSS2) && sector[dasectnum].lotag == ST_1_ABOVE_WATER) || + (sector[dasectnum].lotag == ST_1_ABOVE_WATER && (sprite[spritenum].picnum == LIZMAN || (sprite[spritenum].picnum == LIZTROOP && sprite[spritenum].zvel == 0))) + ) + ) + ))) + { + sprite[spritenum].x = oldx; + sprite[spritenum].y = oldy; + if (sector[dasectnum].lotag == ST_1_ABOVE_WATER && (rr || sprite[spritenum].picnum == LIZMAN)) + sprite[spritenum].ang = (krand() & 2047); + else if ((hittype[spritenum].temp_data[0] & 3) == 1 && (rr || sprite[spritenum].picnum != COMMANDER)) + sprite[spritenum].ang = (krand() & 2047); + setsprite(spritenum, oldx, oldy, sprite[spritenum].z); + if (dasectnum < 0) dasectnum = 0; + return (16384 + dasectnum); + } + if ((retval & 49152) >= 32768 && (hittype[spritenum].cgg == 0)) sprite[spritenum].ang += 768; + } + else + { + if (sprite[spritenum].statnum == 4) + retval = + clipmove(&sprite[spritenum].x, &sprite[spritenum].y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 8L, (4 << 8), (4 << 8), cliptype); + else + retval = + clipmove(&sprite[spritenum].x, &sprite[spritenum].y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), (int)(sprite[spritenum].clipdist << 2), (4 << 8), (4 << 8), cliptype); + } + + if (dasectnum >= 0) + if ((dasectnum != sprite[spritenum].sectnum)) + changespritesect(spritenum, dasectnum); + daz = sprite[spritenum].z + ((zchange * TICSPERFRAME) >> 3); + if ((daz > hittype[spritenum].ceilingz) && (daz <= hittype[spritenum].floorz)) + sprite[spritenum].z = daz; + else + if (retval == 0) + return(16384 + dasectnum); + + return(retval); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +int ssp(short i, unsigned int cliptype) //The set sprite function +{ + spritetype* s; + int movetype; + + s = &sprite[i]; + + movetype = movesprite(i, + (s->xvel * (sintable[(s->ang + 512) & 2047])) >> 14, + (s->xvel * (sintable[s->ang & 2047])) >> 14, s->zvel, + cliptype); + + return (movetype == 0); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void insertspriteq(int i) +{ + if (spriteqamount > 0) + { + if (spriteq[spriteqloc] >= 0) + sprite[spriteq[spriteqloc]].xrepeat = 0; + spriteq[spriteqloc] = i; + spriteqloc = (spriteqloc + 1) % spriteqamount; + } + else sprite[i].xrepeat = sprite[i].yrepeat = 0; +} + +//--------------------------------------------------------------------------- +// +// consolidation of several nearly identical functions +// lotsofmoney -> MONEY / RR_FEATHERS +// lotsofmail -> MAIL +// lotsofpaper -> PAPER +// +//--------------------------------------------------------------------------- + +void lotsofstuff(spritetype* s, short n, int spawntype) +{ + short i, j; + for (i = n; i > 0; i--) + { + short r1 = krand(), r2 = krand(); // using the RANDCORRECT version from RR. + // TRANSITIONAL RedNukem sets the spawner as owner. + j = EGS(s->sectnum, s->x, s->y, s->z - (r2 % (47 << 8)), spawntype, -32, 8, 8, r1 & 2047, 0, 0, 0, 5); + sprite[j].cstat = krand() & 12; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void guts(spritetype* s, short gtype, short n, short p) +{ + int gutz, floorz; + int i=0, j; + int sx, sy; + uint8_t pal; + + if (badguy(s) && s->xrepeat < 16) + sx = sy = 8; + else sx = sy = 32; + + gutz = s->z - (8 << 8); + floorz = getflorzofslope(s->sectnum, s->x, s->y); + + if (gutz > (floorz - (8 << 8))) + gutz = floorz - (8 << 8); + + if (!isRR() && s->picnum == COMMANDER) + gutz -= (24 << 8); + + if (badguy(s) && s->pal == 6) + pal = 6; + else + { + pal = 0; + if (isRRRA()) + { + if (s->picnum == RR_MINION && (s->pal == 8 || s->pal == 19)) pal = s->pal; + } + } + + if (isRR()) + { + sx >>= 1; + sy >>= 1; + } + + for (j = 0; j < n; j++) + { + // RANDCORRECT version from RR. + int a = krand() & 2047; + int r1 = krand(); + int r2 = krand(); + int r3 = krand(); + int r4 = krand(); + int r5 = krand(); + // TRANSITIONAL: owned by a player??? + i = EGS(s->sectnum, s->x + (r5 & 255) - 128, s->y + (r4 & 255) - 128, gutz - (r3 & 8191), gtype, -32, sx, sy, a, 48 + (r2 & 31), -512 - (r1 & 2047), ps[p].i, 5); + if (!isRR() && sprite[i].picnum == JIBS2) + { + sprite[i].xrepeat >>= 2; + sprite[i].yrepeat >>= 2; + } + if (pal != 0) + sprite[i].pal = pal; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void gutsdir(spritetype* s, short gtype, short n, short p) +{ + int gutz, floorz; + short i, j; + char sx, sy; + + if (badguy(s) && s->xrepeat < 16) + sx = sy = 8; + else sx = sy = 32; + + gutz = s->z - (8 << 8); + floorz = getflorzofslope(s->sectnum, s->x, s->y); + + if (gutz > (floorz - (8 << 8))) + gutz = floorz - (8 << 8); + + if (!isRR() && s->picnum == COMMANDER) + gutz -= (24 << 8); + + for (j = 0; j < n; j++) + { + int a = krand() & 2047; + int r1 = krand(); + int r2 = krand(); + // TRANSITIONAL: owned by a player??? + i = EGS(s->sectnum, s->x, s->y, gutz, gtype, -32, sx, sy, a, 256 + (r2 & 127), -512 - (r1 & 2047), ps[p].i, 5); + } +} + +//--------------------------------------------------------------------------- +// +// movesector - why is this in actors.cpp? +// +//--------------------------------------------------------------------------- + +void ms(short i) +{ + //T1,T2 and T3 are used for all the sector moving stuff!!! + + short startwall, endwall, x; + int tx, ty; + spritetype* s; + + s = &sprite[i]; + + s->x += (s->xvel * (sintable[(s->ang + 512) & 2047])) >> 14; + s->y += (s->xvel * (sintable[s->ang & 2047])) >> 14; + + int j = hittype[i].temp_data[1]; + int k = hittype[i].temp_data[2]; + + startwall = sector[s->sectnum].wallptr; + endwall = startwall + sector[s->sectnum].wallnum; + for (x = startwall; x < endwall; x++) + { + rotatepoint( + 0, 0, + msx[j], msy[j], + k & 2047, &tx, &ty); + + dragpoint(x, s->x + tx, s->y + ty); + + j++; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movefta(void) +{ + int x, px, py, sx, sy; + short i, j, p, psect, ssect, nexti; + spritetype* s; + + i = headspritestat[STAT_ZOMBIEACTOR]; + while (i >= 0) + { + nexti = nextspritestat[i]; + + s = &sprite[i]; + p = findplayer(s, &x); + + ssect = psect = s->sectnum; + + if (sprite[ps[p].i].extra > 0) + { + if (x < 30000) + { + hittype[i].timetosleep++; + if (hittype[i].timetosleep >= (x >> 8)) + { + if (badguy(s)) + { + px = ps[p].oposx + 64 - (krand() & 127); + py = ps[p].oposy + 64 - (krand() & 127); + updatesector(px, py, &psect); + if (psect == -1) + { + i = nexti; + continue; + } + sx = s->x + 64 - (krand() & 127); + sy = s->y + 64 - (krand() & 127); + updatesector(px, py, &ssect); + if (ssect == -1) + { + i = nexti; + continue; + } + + if (!isRR() || s->pal == 33 || s->type == RR_VIXEN || + ((isRRRA()) && isIn(s->type, RR_COOT, RR_COOTSTAYPUT, RR_BIKERSTAND, RR_BIKERRIDE, + RR_BIKERRIDEDAISY, RR_MINIONAIRBOAT, RR_HULKAIRBOAT, + RR_DAISYAIRBOAT, RR_JACKOLOPE, RR_BANJOCOOTER, + RR_GUITARBILLY, RR_MAMAJACKOLOPE, RR_BIKERBV, + RR_MAKEOUT, RR_CHEER, RR_CHEERSTAYPUT)) || + (sintable[(s->ang + 512) & 2047] * (px - sx) + sintable[s->ang & 2047] * (py - sy) >= 0)) + { + int r1 = krand(); + int r2 = krand(); + j = cansee(sx, sy, s->z - (r2 % (52 << 8)), s->sectnum, px, py, ps[p].oposz - (r1 % (32 << 8)), ps[p].cursectnum); + } + } + else + { + int r1 = krand(); + int r2 = krand(); + j = cansee(s->x, s->y, s->z - ((r2 & 31) << 8), s->sectnum, ps[p].oposx, ps[p].oposy, ps[p].oposz - ((r1 & 31) << 8), ps[p].cursectnum); + } + + if (j) + { + bool res = (!isRR()) ? + isIn(s->picnum, + RUBBERCAN, + EXPLODINGBARREL, + WOODENHORSE, + HORSEONSIDE, + CANWITHSOMETHING, + CANWITHSOMETHING2, + CANWITHSOMETHING3, + CANWITHSOMETHING4, + FIREBARREL, + FIREVASE, + NUKEBARREL, + NUKEBARRELDENTED, + NUKEBARRELLEAKED, + TRIPBOMB) : + isIn(s->picnum, + RR_1251, + RR_1268, + RR_1187, + RR_1304, + RR_1305, + RR_1306, + RR_1309, + RR_1315, + RR_1317, + RR_1388); + + + if (res) + { + if (sector[s->sectnum].ceilingstat & 1) + s->shade = sector[s->sectnum].ceilingshade; + else s->shade = sector[s->sectnum].floorshade; + + hittype[i].timetosleep = 0; + changespritestat(i, STAT_STANDABLE); + } + else + { +#if 0 + // TRANSITIONAL: RedNukem has this here. Needed? + if (A_CheckSpriteFlags(spriteNum, SFLAG_USEACTIVATOR) && sector[sprite[spriteNum].sectnum].lotag & 16384) break; +#endif + hittype[i].timetosleep = 0; + check_fta_sounds(i); + changespritestat(i, STAT_ACTOR); + } + } + else hittype[i].timetosleep = 0; + } + } + if ((!isRR() || !j) && badguy(s)) + { + if (sector[s->sectnum].ceilingstat & 1) + s->shade = sector[s->sectnum].ceilingshade; + else s->shade = sector[s->sectnum].floorshade; + + if (isRR() && (s->picnum != RR_HEN || s->picnum != RR_COW || s->picnum != RR_PIG || s->picnum != RR_DOGRUN || ((isRRRA()) && s->picnum != RR_JACKOLOPE))) + if (wakeup(i, p)) + { + hittype[i].timetosleep = 0; + check_fta_sounds(i); + changespritestat(i, STAT_ACTOR); + } + + } + } + i = nexti; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +int ifhitsectors(int sectnum) +{ + int i = headspritestat[STAT_MISC]; + if (!isRR()) + { + while (i >= 0) + { + if (sprite[i].picnum == EXPLOSION2 && sectnum == sprite[i].sectnum) + return i; + i = nextspritestat[i]; + } + } + else + { + while (i >= 0) + { + if (sprite[i].picnum == RR_EXPLOSION2 || (sprite[i].picnum == RR_EXPLOSION3 && sectnum == sprite[i].sectnum)) + return i; + i = nextspritestat[i]; + } + } + + return -1; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +int ifhitbyweapon(int sn) +{ + short j, p; + spritetype* npc; + + if (hittype[sn].extra >= 0) + { + if (sprite[sn].extra >= 0) + { + npc = &sprite[sn]; + + if (npc->picnum == APLAYER) + { + if (ud.god && (isRR() || hittype[sn].picnum != SHRINKSPARK)) return -1; + + p = npc->yvel; + j = hittype[sn].owner; + + if (j >= 0 && + sprite[j].picnum == APLAYER && + ud.coop == 1 && + ud.ffire == 0) + return -1; + + npc->extra -= hittype[sn].extra; + + if (j >= 0) + { + if (npc->extra <= 0 && hittype[sn].picnum != pPick2(FREEZEBLAST, RR_ALIENBLAST)) + { + npc->extra = 0; + + ps[p].wackedbyactor = j; + + if (sprite[hittype[sn].owner].picnum == APLAYER && p != sprite[hittype[sn].owner].yvel) + { + // yvel contains player ID + ps[p].frag_ps = sprite[j].yvel; + } + + hittype[sn].owner = ps[p].i; + } + } + + bool res = !isRR() ? + isIn(hittype[sn].picnum, RADIUSEXPLOSION, RPG, HYDRENT, HEAVYHBOMB, SEENINE, OOZFILTER, EXPLODINGBARREL) : + (isIn(hittype[sn].picnum, RR_DYNAMITE, RR_POWDERKEGSPRITE, RR_1228, RR_1273, RR_1315, RR_SEENINE, RR_RADIUSEXPLOSION, RR_CROSSBOW) || + (isRRRA() && hittype[sn].picnum == RR_CHIKENCROSSBOW)); + + int shift = res ? 2 : 1; + ps[p].posxv += hittype[sn].extra * (sintable[(hittype[sn].ang + 512) & 2047]) << shift; + ps[p].posyv += hittype[sn].extra * (sintable[hittype[sn].ang & 2047]) << shift; + } + else + { + if (hittype[sn].extra == 0) + if ((isRR() || hittype[sn].picnum == SHRINKSPARK) && npc->xrepeat < 24) + return -1; + + if (isWorldTour() && hittype[sn].picnum == FIREFLY && npc->xrepeat < 48) + { + if (hittype[sn].picnum != RADIUSEXPLOSION && hittype[sn].picnum != RPG) + return -1; + } + + npc->extra -= hittype[sn].extra; + if (npc->picnum != pPick2(RECON, RR_4989) && npc->owner >= 0 && sprite[npc->owner].statnum < MAXSTATUS) + npc->owner = hittype[sn].owner; + } + + hittype[sn].extra = -1; + return hittype[sn].picnum; + } + } + + + if (ud.multimode < 2 || !isWorldTour() + || hittype[sn].picnum != FLAMETHROWERFLAME + || hittype[sn].extra >= 0 + || sprite[sn].extra > 0 + || sprite[sn].picnum != APLAYER + || ps[sprite[sn].yvel].numloogs > 0 + || hittype[sn].owner < 0) + { + hittype[sn].extra = -1; + return -1; + } + else + { + p = sprite[sn].yvel; + sprite[sn].extra = 0; + ps[p].wackedbyactor = (short)hittype[sn].owner; + + if (sprite[hittype[sn].owner].picnum == APLAYER && p != hittype[sn].owner) + ps[p].frag_ps = (short)hittype[sn].owner; + + hittype[sn].owner = ps[p].i; + hittype[sn].extra = -1; + + return FLAMETHROWERFLAME; + } + + + hittype[sn].extra = -1; + return -1; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movecyclers(void) +{ + short q, j, x, t, s, * c; + walltype* wal; + char cshade; + + for (q = numcyclers - 1; q >= 0; q--) + { + + c = &cyclers[q][0]; + s = c[0]; + + t = c[3]; + j = t + (sintable[c[1] & 2047] >> 10); + cshade = c[2]; + + if (j < cshade) j = cshade; + else if (j > t) j = t; + + c[1] += sector[s].extra; + if (c[5]) + { + wal = &wall[sector[s].wallptr]; + for (x = sector[s].wallnum; x > 0; x--, wal++) + if (wal->hitag != 1) + { + wal->shade = j; + + if ((wal->cstat & 2) && wal->nextwall >= 0) + wall[wal->nextwall].shade = j; + + } + sector[s].floorshade = sector[s].ceilingshade = j; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movedummyplayers(void) +{ + short i, p, nexti; + + i = headspritestat[STAT_DUMMYPLAYER]; + while (i >= 0) + { + nexti = nextspritestat[i]; + + p = sprite[sprite[i].owner].yvel; + + if ((!isRR() && ps[p].on_crane >= 0) || sector[ps[p].cursectnum].lotag != 1 || sprite[ps[p].i].extra <= 0) + { + ps[p].dummyplayersprite = -1; + deletesprite(i); + i = nexti; + continue; + } + else + { + if (ps[p].on_ground && ps[p].on_warping_sector == 1 && sector[ps[p].cursectnum].lotag == 1) + { + sprite[i].cstat = 257; + sprite[i].z = sector[sprite[i].sectnum].ceilingz + (27 << 8); + sprite[i].ang = ps[p].q16ang >> FRACBITS; + if (hittype[i].temp_data[0] == 8) + hittype[i].temp_data[0] = 0; + else hittype[i].temp_data[0]++; + } + else + { + if (sector[sprite[i].sectnum].lotag != 2) sprite[i].z = sector[sprite[i].sectnum].floorz; + sprite[i].cstat = (short)32768; + } + } + + sprite[i].x += (ps[p].posx - ps[p].oposx); + sprite[i].y += (ps[p].posy - ps[p].oposy); + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + i = nexti; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +int otherp; +void moveplayers(void) //Players +{ + short i, nexti; + int otherx; + spritetype* s; + struct player_struct* p; + + i = headspritestat[STAT_PLAYER]; + while (i >= 0) + { + nexti = nextspritestat[i]; + + s = &sprite[i]; + p = &ps[s->yvel]; + if (s->owner >= 0) + { + if (p->newowner >= 0) //Looking thru the camera + { + s->x = p->oposx; + s->y = p->oposy; + hittype[i].bposz = s->z = p->oposz + PHEIGHT; + s->ang = p->oq16ang >> FRACBITS; + setsprite(i, s->x, s->y, s->z); + } + else + { + if (ud.multimode > 1) + otherp = findotherplayer(s->yvel, &otherx); + else + { + otherp = s->yvel; + otherx = 0; + } + + execute(i, s->yvel, otherx); + + p->oq16ang = p->q16ang; + + if (ud.multimode > 1) + if (sprite[ps[otherp].i].extra > 0) + { + if (s->yrepeat > 32 && sprite[ps[otherp].i].yrepeat < 32) + { + if (otherx < 1400 && p->knee_incs == 0) + { + p->knee_incs = 1; + p->weapon_pos = -1; + p->actorsqu = ps[otherp].i; + } + } + } + if (ud.god) + { + s->extra = p->max_player_health; + s->cstat = 257; + if (!isWW2GI() && !isRR()) + p->jetpack_amount = 1599; + } + + + if (s->extra > 0) + { + // currently alive... + + hittype[i].owner = i; + + if (ud.god == 0) + if (ceilingspace(s->sectnum) || floorspace(s->sectnum)) + quickkill(p); + } + else + { + + p->posx = s->x; + p->posy = s->y; + p->posz = s->z - (20 << 8); + + p->newowner = -1; + + if (p->wackedbyactor >= 0 && sprite[p->wackedbyactor].statnum < MAXSTATUS) + { + int ang = p->q16ang >> FRACBITS; + ang += getincangle(ang, getangle(sprite[p->wackedbyactor].x - p->posx, sprite[p->wackedbyactor].y - p->posy)) >> 1; + ang &= 2047; + p->q16ang = ang << FRACBITS; + } + + } + s->ang = p->q16ang >> FRACBITS; + } + } + else + { + if (p->holoduke_on == -1) + { + deletesprite(i); + i = nexti; + continue; + } + + hittype[i].bposx = s->x; + hittype[i].bposy = s->y; + hittype[i].bposz = s->z; + + s->cstat = 0; + + if (s->xrepeat < 42) + { + s->xrepeat += 4; + s->cstat |= 2; + } + else s->xrepeat = 42; + if (s->yrepeat < 36) + s->yrepeat += 4; + else + { + s->yrepeat = 36; + if (sector[s->sectnum].lotag != ST_2_UNDERWATER) + makeitfall(i); + if (s->zvel == 0 && sector[s->sectnum].lotag == ST_1_ABOVE_WATER) + s->z += (32 << 8); + } + + if (s->extra < 8) + { + s->xvel = 128; + s->ang = p->q16ang >> FRACBITS; + s->extra++; + //IFMOVING; // JBF 20040825: is really "if (ssp(i,CLIPMASK0)) ;" which is probably + ssp(i, CLIPMASK0); // not the safest of ideas because a zealous optimiser probably sees + // it as redundant, so I'll call the "ssp(i,CLIPMASK0)" explicitly. + } + else + { + s->ang = 2047 - (p->q16ang >> FRACBITS); + setsprite(i, s->x, s->y, s->z); + } + } + + if (sector[s->sectnum].ceilingstat & 1) + s->shade += (sector[s->sectnum].ceilingshade - s->shade) >> 1; + else + s->shade += (sector[s->sectnum].floorshade - s->shade) >> 1; + + i = nexti; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movefx(void) +{ + short i, j, nexti, p; + int x, ht; + spritetype* s; + + i = headspritestat[STAT_FX]; + while (i >= 0) + { + s = &sprite[i]; + + nexti = nextspritestat[i]; + + switch (s->picnum) + { + case RESPAWN: + if (sprite[i].extra == 66) + { + j = spawn(i, sprite[i].hitag); + if (isRRRA()) + { + sprite[j].pal = sprite[i].pal; + if (sprite[j].picnum == RR_MAMAJACKOLOPE) + { + if (sprite[j].pal == 30) + { + sprite[j].xrepeat = 26; + sprite[j].yrepeat = 26; + sprite[j].clipdist = 75; + } + else if (sprite[j].pal == 31) + { + sprite[j].xrepeat = 36; + sprite[j].yrepeat = 36; + sprite[j].clipdist = 100; + } + else if (sprite[j].pal == 32) + { + sprite[j].xrepeat = 50; + sprite[j].yrepeat = 50; + sprite[j].clipdist = 100; + } + else + { + sprite[j].xrepeat = 50; + sprite[j].yrepeat = 50; + sprite[j].clipdist = 100; + } + } + + if (sprite[j].pal == 8) + { + sprite[j].cstat |= 2; + } + + if (sprite[j].pal != 6) + { + deletesprite(i); + i = nexti; + continue; + } + sprite[i].extra = (66 - 13); + sprite[j].pal = 0; + } + else + { + deletesprite(i); + i = nexti; + continue; + } + } + else if (sprite[i].extra > (66 - 13)) + sprite[i].extra++; + break; + + case MUSICANDSFX: + + ht = s->hitag; + + if (hittype[i].temp_data[1] != (int)SoundEnabled()) + { + hittype[i].temp_data[1] = SoundEnabled(); + hittype[i].temp_data[0] = 0; + } + + if (s->lotag >= 1000 && s->lotag < 2000) + { + x = ldist(&sprite[ps[screenpeek].i], s); + if (x < ht && hittype[i].temp_data[0] == 0) + { + FX_SetReverb(s->lotag - 1000); + hittype[i].temp_data[0] = 1; + } + if (x >= ht && hittype[i].temp_data[0] == 1) + { + FX_SetReverb(0); + FX_SetReverbDelay(0); + hittype[i].temp_data[0] = 0; + } + } + else if (s->lotag < 999 && (unsigned)sector[s->sectnum].lotag < ST_9_SLIDING_ST_DOOR && snd_ambience && sector[sprite[i].sectnum].floorz != sector[sprite[i].sectnum].ceilingz) + { + auto flags = S_GetUserFlags(s->lotag); + if (flags & SF_MSFX) + { + int x = dist(&sprite[ps[screenpeek].i], s); + + if (x < ht && hittype[i].temp_data[0] == 0) + { + // Start playing an ambience sound. + A_PlaySound(s->lotag, i, CHAN_AUTO, CHANF_LOOP); + hittype[i].temp_data[0] = 1; // AMBIENT_SFX_PLAYING + } + else if (x >= ht && hittype[i].temp_data[0] == 1) + { + // Stop playing ambience sound because we're out of its range. + S_StopEnvSound(s->lotag, i); + } + } + + if ((flags & (SF_GLOBAL | SF_DTAG)) == SF_GLOBAL) + { + if (hittype[i].temp_data[4] > 0) hittype[i].temp_data[4]--; + else for (p = connecthead; p >= 0; p = connectpoint2[p]) + if (p == myconnectindex && ps[p].cursectnum == s->sectnum) + { + S_PlaySound(s->lotag + (unsigned)global_random % (s->hitag + 1)); + hittype[i].temp_data[4] = 26 * 40 + (global_random % (26 * 40)); + } + } + } + break; + } + i = nexti; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movefallers(void) +{ + short i, nexti, sect, j; + spritetype* s; + int x; + + i = headspritestat[STAT_FALLER]; + while (i >= 0) + { + nexti = nextspritestat[i]; + s = &sprite[i]; + + sect = s->sectnum; + + if (hittype[i].temp_data[0] == 0) + { + s->z -= (16 << 8); + hittype[i].temp_data[1] = s->ang; + x = s->extra; + j = ifhitbyweapon(i); + if (j >= 0) + { + bool res = !isRR() ? + isIn(j, FIREEXT, RPG, RADIUSEXPLOSION, SEENINE, OOZFILTER) : + (isIn(j, RR_CROSSBOW, RR_RADIUSEXPLOSION, RR_SEENINE, RR_OOZFILTER) || (isRRRA() && j == RR_CHIKENCROSSBOW)); + + if (res) + { + if (s->extra <= 0) + { + hittype[i].temp_data[0] = 1; + j = headspritestat[12]; + while (j >= 0) + { + if (sprite[j].hitag == sprite[i].hitag) + { + hittype[j].temp_data[0] = 1; + sprite[j].cstat &= (65535 - 64); + if (!isRR() ? isIn(j, CEILINGSTEAM, STEAM) : isIn(j, RR_CEILINGSTEAM, RR_STEAM)) + sprite[j].cstat |= 32768; + } + j = nextspritestat[j]; + } + } + } + else + { + hittype[i].extra = 0; + s->extra = x; + } + } + s->ang = hittype[i].temp_data[1]; + s->z += (16 << 8); + } + else if (hittype[i].temp_data[0] == 1) + { + if (s->lotag > 0) + { + s->lotag -= 3; + if (isRR()) + { + s->xvel = (64 + krand()) & 127; + s->zvel = -(1024 + (krand() & 1023)); + } + else if (s->lotag <= 0) + { + s->xvel = (32 + (krand() & 63)); + s->zvel = -(1024 + (krand() & 1023)); + } + } + else + { + if (s->xvel > 0) + { + s->xvel -= isRR()? 2 : 8; + ssp(i, CLIPMASK0); + } + + if (floorspace(s->sectnum)) x = 0; + else + { + if (ceilingspace(s->sectnum)) + x = gc / 6; + else + x = gc; + } + + if (s->z < (sector[sect].floorz - FOURSLEIGHT)) + { + s->zvel += x; + if (s->zvel > 6144) + s->zvel = 6144; + s->z += s->zvel; + } + if ((sector[sect].floorz - s->z) < (16 << 8)) + { + j = 1 + (krand() & 7); + for (x = 0; x < j; x++) RANDOMSCRAP(s, i); + deletesprite(i); + } + } + } + + i = nexti; + } +} + +//--------------------------------------------------------------------------- +// +// split out of movestandables +// +//--------------------------------------------------------------------------- + +static void movecrane(int i) +{ + auto t = &hittype[i].temp_data[0]; + auto s = &sprite[i]; + int sect = s->sectnum; + int x; + int crane = pPick(CRANE); + + //t[0] = state + //t[1] = checking sector number + + if (s->xvel) getglobalz(i); + + if (t[0] == 0) //Waiting to check the sector + { + int j = headspritesect[t[1]]; + while (j >= 0) + { + int nextj = nextspritesect[j]; + switch (sprite[j].statnum) + { + case STAT_ACTOR: + case STAT_ZOMBIEACTOR: + case STAT_STANDABLE: + case STAT_PLAYER: + s->ang = getangle(msx[t[4] + 1] - s->x, msy[t[4] + 1] - s->y); + setsprite(j, msx[t[4] + 1], msy[t[4] + 1], sprite[j].z); + t[0]++; + deletesprite(i); + return; + } + j = nextj; + } + } + + else if (t[0] == 1) + { + if (s->xvel < 184) + { + s->picnum = crane + 1; + s->xvel += 8; + } + //IFMOVING; // JBF 20040825: see my rant above about this + ssp(i, CLIPMASK0); + if (sect == t[1]) + t[0]++; + } + else if (t[0] == 2 || t[0] == 7) + { + s->z += (1024 + 512); + + if (t[0] == 2) + { + if ((sector[sect].floorz - s->z) < (64 << 8)) + if (s->picnum > crane) s->picnum--; + + if ((sector[sect].floorz - s->z) < (4096 + 1024)) + t[0]++; + } + if (t[0] == 7) + { + if ((sector[sect].floorz - s->z) < (64 << 8)) + { + if (s->picnum > crane) s->picnum--; + else + { + if (s->owner == -2) + { + auto p = findplayer(s, &x); + spritesound(isRR() ? 390 : DUKE_GRUNT, ps[p].i); + if (ps[p].on_crane == i) + ps[p].on_crane = -1; + } + t[0]++; + s->owner = -1; + } + } + } + } + else if (t[0] == 3) + { + s->picnum++; + if (s->picnum == (crane + 2)) + { + auto p = checkcursectnums(t[1]); + if (p >= 0 && ps[p].on_ground) + { + s->owner = -2; + ps[p].on_crane = i; + spritesound(isRR() ? 390 : DUKE_GRUNT, ps[p].i); + ps[p].q16ang = (s->ang + 1024) << FRACBITS; + } + else + { + int j = headspritesect[t[1]]; + while (j >= 0) + { + switch (sprite[j].statnum) + { + case 1: + case 6: + s->owner = j; + break; + } + j = nextspritesect[j]; + } + } + + t[0]++;//Grabbed the sprite + t[2] = 0; + return; + } + } + else if (t[0] == 4) //Delay before going up + { + t[2]++; + if (t[2] > 10) + t[0]++; + } + else if (t[0] == 5 || t[0] == 8) + { + if (t[0] == 8 && s->picnum < (crane + 2)) + if ((sector[sect].floorz - s->z) > 8192) + s->picnum++; + + if (s->z < msx[t[4] + 2]) + { + t[0]++; + s->xvel = 0; + } + else + s->z -= (1024 + 512); + } + else if (t[0] == 6) + { + if (s->xvel < 192) + s->xvel += 8; + s->ang = getangle(msx[t[4]] - s->x, msy[t[4]] - s->y); + //IFMOVING; // JBF 20040825: see my rant above about this + ssp(i, CLIPMASK0); + if (((s->x - msx[t[4]]) * (s->x - msx[t[4]]) + (s->y - msy[t[4]]) * (s->y - msy[t[4]])) < (128 * 128)) + t[0]++; + } + + else if (t[0] == 9) + t[0] = 0; + + setsprite(msy[t[4] + 2], s->x, s->y, s->z - (34 << 8)); + + if (s->owner != -1) + { + auto p = findplayer(s, &x); + + int j = ifhitbyweapon(i); + if (j >= 0) + { + if (s->owner == -2) + if (ps[p].on_crane == i) + ps[p].on_crane = -1; + s->owner = -1; + s->picnum = crane; + return; + } + + if (s->owner >= 0) + { + setsprite(s->owner, s->x, s->y, s->z); + + hittype[s->owner].bposx = s->x; + hittype[s->owner].bposy = s->y; + hittype[s->owner].bposz = s->z; + + s->zvel = 0; + } + else if (s->owner == -2) + { + auto ang = ps[p].q16ang >> FRACBITS; + ps[p].oposx = ps[p].posx = s->x - (sintable[(ang + 512) & 2047] >> 6); + ps[p].oposy = ps[p].posy = s->y - (sintable[ang & 2047] >> 6); + ps[p].oposz = ps[p].posz = s->z + (2 << 8); + setsprite(ps[p].i, ps[p].posx, ps[p].posy, ps[p].posz); + ps[p].cursectnum = sprite[ps[p].i].sectnum; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movefountain(int i) +{ + auto t = &hittype[i].temp_data[0]; + auto s = &sprite[i]; + int x; + if (t[0] > 0) + { + if (t[0] < 20) + { + t[0]++; + + s->picnum++; + + if (s->picnum == (pPick(WATERFOUNTAIN) + 3)) + s->picnum = pPick(WATERFOUNTAIN) + 1; + } + else + { + findplayer(s, &x); + + if (x > 512) + { + t[0] = 0; + s->picnum = pPick(WATERFOUNTAIN); + } + else t[0] = 1; + } + } +} +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void moveflammable(int i) +{ + auto s = &sprite[i]; + int j; + if (hittype[i].temp_data[0] == 1) + { + hittype[i].temp_data[1]++; + if ((hittype[i].temp_data[1] & 3) > 0) return; + + if (!isRR() && s->picnum == TIRE && hittype[i].temp_data[1] == 32) + { + s->cstat = 0; + j = spawn(i, BLOODPOOL); + sprite[j].shade = 127; + } + else + { + if (s->shade < 64) s->shade++; + else + { + deletesprite(i); + return; + } + } + + j = s->xrepeat - (krand() & 7); + if (j < 10) + { + deletesprite(i); + return; + } + + s->xrepeat = j; + + j = s->yrepeat - (krand() & 7); + if (j < 4) + { + deletesprite(i); + return; + } + s->yrepeat = j; + } + if (!isRR() && s->picnum == BOX) + { + makeitfall(i); + hittype[i].ceilingz = sector[s->sectnum].ceilingz; + } +} + +//--------------------------------------------------------------------------- +// +// Duke only +// +//--------------------------------------------------------------------------- + +static void movetripbomb(int i) +{ + auto s = &sprite[i]; + int j, x; + int lTripBombControl = GetGameVar("TRIPBOMB_CONTROL", TRIPBOMB_TRIPWIRE, -1, -1); + if (lTripBombControl & TRIPBOMB_TIMER) + { + // we're on a timer.... + if (s->extra >= 0) + { + s->extra--; + if (s->extra == 0) + { + hittype[i].temp_data[2] = 16; + spritesound(LASERTRIP_ARMING, i); + } + } + } + if (hittype[i].temp_data[2] > 0) + { + hittype[i].temp_data[2]--; + if (hittype[i].temp_data[2] == 8) + { + spritesound(LASERTRIP_EXPLODE, i); + for (j = 0; j < 5; j++) RANDOMSCRAP(s, i); + x = s->extra; + hitradius(i, tripbombblastradius, x >> 2, x >> 1, x - (x >> 2), x); + + j = spawn(i, EXPLOSION2); + sprite[j].ang = s->ang; + sprite[j].xvel = 348; + ssp(j, CLIPMASK0); + + j = headspritestat[5]; + while (j >= 0) + { + if (sprite[j].picnum == LASERLINE && s->hitag == sprite[j].hitag) + sprite[j].xrepeat = sprite[j].yrepeat = 0; + j = nextspritestat[j]; + } + deletesprite(i); + } + return; + } + else + { + x = s->extra; + s->extra = 1; + int16_t l = s->ang; + j = ifhitbyweapon(i); + if (j >= 0) + { + hittype[i].temp_data[2] = 16; + } + s->extra = x; + s->ang = l; + } + + if (hittype[i].temp_data[0] < 32) + { + findplayer(s, &x); + if (x > 768) hittype[i].temp_data[0]++; + else if (hittype[i].temp_data[0] > 16) hittype[i].temp_data[0]++; + } + if (hittype[i].temp_data[0] == 32) + { + int16_t l = s->ang; + s->ang = hittype[i].temp_data[5]; + + hittype[i].temp_data[3] = s->x; hittype[i].temp_data[4] = s->y; + s->x += sintable[(hittype[i].temp_data[5] + 512) & 2047] >> 9; + s->y += sintable[(hittype[i].temp_data[5]) & 2047] >> 9; + s->z -= (3 << 8); + setsprite(i, s->x, s->y, s->z); + + int16_t m; + x = hitasprite(i, &m); + + hittype[i].lastvx = x; + + s->ang = l; + + int k = 0; + + if (lTripBombControl & TRIPBOMB_TRIPWIRE) + { + // we're on a trip wire + while (x > 0) + { + j = spawn(i, LASERLINE); + setsprite(j, sprite[j].x, sprite[j].y, sprite[j].z); + sprite[j].hitag = s->hitag; + hittype[j].temp_data[1] = sprite[j].z; + + s->x += sintable[(hittype[i].temp_data[5] + 512) & 2047] >> 4; + s->y += sintable[(hittype[i].temp_data[5]) & 2047] >> 4; + + if (x < 1024) + { + sprite[j].xrepeat = x >> 5; + break; + } + x -= 1024; + } + } + + hittype[i].temp_data[0]++; + s->x = hittype[i].temp_data[3]; s->y = hittype[i].temp_data[4]; + s->z += (3 << 8); + setsprite(i, s->x, s->y, s->z); + hittype[i].temp_data[3] = 0; + if (m >= 0 && lTripBombControl & TRIPBOMB_TRIPWIRE) + { + hittype[i].temp_data[2] = 13; + spritesound(LASERTRIP_ARMING, i); + } + else hittype[i].temp_data[2] = 0; + } + if (hittype[i].temp_data[0] == 33) + { + hittype[i].temp_data[1]++; + + + hittype[i].temp_data[3] = s->x; hittype[i].temp_data[4] = s->y; + s->x += sintable[(hittype[i].temp_data[5] + 512) & 2047] >> 9; + s->y += sintable[(hittype[i].temp_data[5]) & 2047] >> 9; + s->z -= (3 << 8); + setsprite(i, s->x, s->y, s->z); + + int16_t m; + x = hitasprite(i, &m); + + s->x = hittype[i].temp_data[3]; s->y = hittype[i].temp_data[4]; + s->z += (3 << 8); + setsprite(i, s->x, s->y, s->z); + + if (hittype[i].lastvx != x && lTripBombControl & TRIPBOMB_TRIPWIRE) + { + hittype[i].temp_data[2] = 13; + spritesound(LASERTRIP_ARMING, i); + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void detonate(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + earthquaketime = 16; + + int j = headspritestat[STAT_EFFECTOR]; + while (j >= 0) + { + if (s->hitag == sprite[j].hitag) + { + if (sprite[j].lotag == SE_13_EXPLOSIVE) + { + if (hittype[j].temp_data[2] == 0) + hittype[j].temp_data[2] = 1; + } + else if (sprite[j].lotag == SE_8_UP_OPEN_DOOR_LIGHTS) + hittype[j].temp_data[4] = 1; + else if (sprite[j].lotag == SE_18_INCREMENTAL_SECTOR_RISE_FALL) + { + if (hittype[j].temp_data[0] == 0) + hittype[j].temp_data[0] = 1; + } + else if (sprite[j].lotag == SE_21_DROP_FLOOR) + hittype[j].temp_data[0] = 1; + } + j = nextspritestat[j]; + } + + s->z -= (32 << 8); + + if ((t[3] == 1 && s->xrepeat) || s->lotag == -99) + { + int x = s->extra; + spawn(i, EXPLOSION2); + hitradius(i, seenineblastradius, x >> 2, x - (x >> 1), x - (x >> 2), x); + spritesound(PIPEBOMB_EXPLODE, i); + } + + if (s->xrepeat) + for (int x = 0; x < 8; x++) RANDOMSCRAP(s, i); + + deletesprite(i); + +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movecrack(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + if (s->hitag > 0) + { + t[0] = s->cstat; + t[1] = s->ang; + int j = ifhitbyweapon(i); + + bool res = !isRR() ? + isIn(j, FIREEXT, RPG, RADIUSEXPLOSION, SEENINE, OOZFILTER) : + (isIn(j, RR_CROSSBOW, RR_RADIUSEXPLOSION, RR_SEENINE, RR_OOZFILTER) || (isRRRA() && j == RR_CHIKENCROSSBOW)); + + if (res) + { + j = headspritestat[STAT_STANDABLE]; + while (j >= 0) + { + if (s->hitag == sprite[j].hitag && (isRR() ? isIn(sprite[j].picnum, RR_OOZFILTER, RR_SEENINE) : isIn(sprite[j].picnum, OOZFILTER, SEENINE))) + if (sprite[j].shade != -32) + sprite[j].shade = -32; + j = nextspritestat[j]; + } + detonate(i); + } + else + { + s->cstat = t[0]; + s->ang = t[1]; + s->extra = 0; + } + } +} + +//--------------------------------------------------------------------------- +// +// Duke only +// +//--------------------------------------------------------------------------- + +static void movefireext(int i) +{ + int j = ifhitbyweapon(i); + if (j == -1) return; + + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + + for (int k = 0; k < 16; k++) + { + j = EGS(sprite[i].sectnum, sprite[i].x, sprite[i].y, sprite[i].z - (krand() % (48 << 8)), SCRAP3 + (krand() & 3), -8, 48, 48, krand() & 2047, (krand() & 63) + 64, -(krand() & 4095) - (sprite[i].zvel >> 2), i, 5); + sprite[j].pal = 2; + } + + spawn(i, EXPLOSION2); + spritesound(PIPEBOMB_EXPLODE, i); + spritesound(GLASS_HEAVYBREAK, i); + + if (s->hitag > 0) + { + j = headspritestat[6]; + while (j >= 0) + { + if (s->hitag == sprite[j].hitag && (sprite[j].picnum == OOZFILTER || sprite[j].picnum == SEENINE)) + if (sprite[j].shade != -32) + sprite[j].shade = -32; + j = nextspritestat[j]; + } + + int x = s->extra; + spawn(i, EXPLOSION2); + hitradius(i, pipebombblastradius, x >> 2, x - (x >> 1), x - (x >> 2), x); + spritesound(PIPEBOMB_EXPLODE, i); + detonate(i); + } + else + { + hitradius(i, seenineblastradius, 10, 15, 20, 25); + deletesprite(i); + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void moveooz(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + int j; + if (s->shade != -32 && s->shade != -33) + { + if (s->xrepeat) + j = (ifhitbyweapon(i) >= 0); + else + j = 0; + + if (j || s->shade == -31) + { + if (j) s->lotag = 0; + + t[3] = 1; + + j = headspritestat[STAT_STANDABLE]; + while (j >= 0) + { + if (s->hitag == sprite[j].hitag && (sprite[j].picnum == pPick(SEENINE) || sprite[j].picnum == pPick(OOZFILTER))) + sprite[j].shade = -32; + j = nextspritestat[j]; + } + } + } + else + { + if (s->shade == -32) + { + if (s->lotag > 0) + { + s->lotag -= 3; + if (s->lotag <= 0) s->lotag = -99; + } + else + s->shade = -33; + } + else + { + if (s->xrepeat > 0) + { + hittype[i].temp_data[2]++; + if (hittype[i].temp_data[2] == 3) + { + if (s->picnum == pPick(OOZFILTER)) + { + hittype[i].temp_data[2] = 0; + detonate(i); + return; + } + if (s->picnum != (pPick(SEENINEDEAD) + 1)) + { + hittype[i].temp_data[2] = 0; + + if (s->picnum == pPick(SEENINEDEAD)) s->picnum++; + else if (s->picnum == pPick(SEENINE)) + s->picnum = pPick(SEENINEDEAD); + } + else + { + detonate(i); + return; + } + } + return; + } + detonate(i); + return; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movemasterswitch(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + if (s->yvel == 1) + { + s->hitag--; + if (s->hitag <= 0) + { + operatesectors(s->sectnum, i); + + int j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].statnum == 3) + { + switch (sprite[j].lotag) + { + case SE_2_EARTHQUAKE: + case SE_21_DROP_FLOOR: + case SE_31_FLOOR_RISE_FALL: + case SE_32_CEILING_RISE_FALL: + case SE_36_PROJ_SHOOTER: + hittype[j].temp_data[0] = 1; + break; + case SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT: + hittype[j].temp_data[4] = 1; + break; + } + } + else if (sprite[j].statnum == 6) + { + if (sprite[j].picnum == pPick(SEENINE) || sprite[j].picnum == pPick(OOZFILTER)) + { + sprite[j].shade = -31; + } + } + j = nextspritesect[j]; + } + deletesprite(i); + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void moveviewscreen(int i) +{ + auto s = &sprite[i]; + if (s->xrepeat == 0) deletesprite(i); + else + { + int x; + findplayer(s, &x); + + if (x < 2048) + { +#if 0 + if (SP == 1) + camsprite = i; +#endif + } + else if (camsprite != -1 && hittype[i].temp_data[0] == 1) + { + camsprite = -1; + s->yvel = 0; + hittype[i].temp_data[0] = 0; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movetrash(int i) +{ + auto s = &sprite[i]; + if (s->xvel == 0) s->xvel = 1; + if (ssp(i, CLIPMASK0)) + { + makeitfall(i); + if (krand() & 1) s->zvel -= 256; + if (klabs(s->xvel) < 48) + s->xvel += (krand() & 3); + } + else deletesprite(i); +} + +//--------------------------------------------------------------------------- +// +// Duke only +// +//--------------------------------------------------------------------------- + +static void movesidebolt(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + int x; + int sect = s->sectnum; + + auto p = findplayer(s, &x); + if (x > 20480) return; + +CLEAR_THE_BOLT2: + if (t[2]) + { + t[2]--; + return; + } + if ((s->xrepeat | s->yrepeat) == 0) + { + s->xrepeat = t[0]; + s->yrepeat = t[1]; + } + if ((krand() & 8) == 0) + { + t[0] = s->xrepeat; + t[1] = s->yrepeat; + t[2] = global_random & 4; + s->xrepeat = s->yrepeat = 0; + goto CLEAR_THE_BOLT2; + } + s->picnum++; + +#if 0 + // content of l was undefined. + if (l & 1) s->cstat ^= 2; +#endif + + if ((krand() & 1) && sector[sect].floorpicnum == HURTRAIL) + spritesound(SHORT_CIRCUIT, i); + + if (s->picnum == SIDEBOLT1 + 4) s->picnum = SIDEBOLT1; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movebolt(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + int x; + int sect = s->sectnum; + + auto p = findplayer(s, &x); + if (x > 20480) return; + + if (t[3] == 0) + t[3] = sector[sect].floorshade; + +CLEAR_THE_BOLT: + if (t[2]) + { + t[2]--; + sector[sect].floorshade = 20; + sector[sect].ceilingshade = 20; + return; + } + if ((s->xrepeat | s->yrepeat) == 0) + { + s->xrepeat = t[0]; + s->yrepeat = t[1]; + } + else if ((krand() & 8) == 0) + { + t[0] = s->xrepeat; + t[1] = s->yrepeat; + t[2] = global_random & 4; + s->xrepeat = s->yrepeat = 0; + goto CLEAR_THE_BOLT; + } + s->picnum++; + + int l = global_random & 7; + s->xrepeat = l + 8; + + if (l & 1) s->cstat ^= 2; + + auto bolt1 = pPick(BOLT1); + if (s->picnum == (bolt1 + 1) && (isRR() ? (krand() & 1) != 0 : (krand() & 7) == 0) && sector[sect].floorpicnum == pPick(HURTRAIL) ) + spritesound(SHORT_CIRCUIT, i); + + if (s->picnum == bolt1 + 4) s->picnum = bolt1; + + if (s->picnum & 1) + { + sector[sect].floorshade = 0; + sector[sect].ceilingshade = 0; + } + else + { + sector[sect].floorshade = 20; + sector[sect].ceilingshade = 20; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movewaterdrip(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + int sect = s->sectnum; + + if (t[1]) + { + t[1]--; + if (t[1] == 0) + s->cstat &= 32767; + } + else + { + makeitfall(i); + ssp(i, CLIPMASK0); + if (s->xvel > 0) s->xvel -= 2; + + if (s->zvel == 0) + { + s->cstat |= 32768; + + if (s->pal != 2 && (isRR() || s->hitag == 0)) + spritesound(SOMETHING_DRIPPING, i); + + if (sprite[s->owner].picnum != pPick(WATERDRIP)) + { + deletesprite(i); + } + else + { + hittype[i].bposz = s->z = t[0]; + t[1] = 48 + (krand() & 31); + } + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movedoorshock(int i) +{ + auto s = &sprite[i]; + int sect = s->sectnum; + int j = abs(sector[sect].ceilingz - sector[sect].floorz) >> 9; + s->yrepeat = j + 4; + s->xrepeat = 16; + s->z = sector[sect].floorz; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movetouchplate(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + int sect = s->sectnum; + int x; + int p; + + if (t[1] == 1 && s->hitag >= 0) //Move the sector floor + { + x = sector[sect].floorz; + + if (t[3] == 1) + { + if (x >= t[2]) + { + sector[sect].floorz = x; + t[1] = 0; + } + else + { + sector[sect].floorz += sector[sect].extra; + p = checkcursectnums(sect); + if (p >= 0) ps[p].posz += sector[sect].extra; + } + } + else + { + if (x <= s->z) + { + sector[sect].floorz = s->z; + t[1] = 0; + } + else + { + sector[sect].floorz -= sector[sect].extra; + p = checkcursectnums(sect); + if (p >= 0) + ps[p].posz -= sector[sect].extra; + } + } + return; + } + + if (t[5] == 1) return; + + p = checkcursectnums(sect); + if (p >= 0 && (ps[p].on_ground || s->ang == 512)) + { + if (t[0] == 0 && !check_activator_motion(s->lotag)) + { + t[0] = 1; + t[1] = 1; + t[3] = !t[3]; + operatemasterswitches(s->lotag); + operateactivators(s->lotag, p); + if (s->hitag > 0) + { + s->hitag--; + if (s->hitag == 0) t[5] = 1; + } + } + } + else t[0] = 0; + + if (t[1] == 1) + { + int j = headspritestat[STAT_STANDABLE]; + while (j >= 0) + { + if (j != i && sprite[j].picnum == TOUCHPLATE && sprite[j].lotag == s->lotag) + { + hittype[j].temp_data[1] = 1; + hittype[j].temp_data[3] = t[3]; + } + j = nextspritestat[j]; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movecanwithsomething(int i) +{ + auto s = &sprite[i]; + makeitfall(i); + int j = ifhitbyweapon(i); + if (j >= 0) + { + spritesound(VENT_BUST, i); + for (j = 0; j < 10; j++) + RANDOMSCRAP(s, i); + + if (s->lotag) spawn(i, s->lotag); + + deletesprite(i); + } +} + +//--------------------------------------------------------------------------- +// +// this has been broken up into lots of smaller subfunctions +// +//--------------------------------------------------------------------------- + +void movestandables(void) +{ + int nexti; + + for (int i = headspritestat[STAT_STANDABLE]; i >= 0; i = nexti) + { + nexti = nextspritestat[i]; + + auto s = &sprite[i]; + int picnum = s->picnum; + + if (s->sectnum < 0) + { + deletesprite(i); + continue; + } + + hittype[i].bposx = s->x; + hittype[i].bposy = s->y; + hittype[i].bposz = s->z; + + + if (picnum >= pPick(CRANE) && picnum <= pPick(CRANE) +3) + { + movecrane(i); + } + + else if (picnum >= pPick(WATERFOUNTAIN) && picnum <= pPick(WATERFOUNTAIN) + 3) + { + movefountain(i); + } + + else if (AFLAMABLE(picnum)) + { + moveflammable(i); + } + + else if (!isRR() && picnum == TRIPBOMB) + { + movetripbomb(i); + } + + else if (picnum >= pPick(CRACK1) && picnum <= pPick(CRACK1)+3) + { + movecrack(i); + } + + else if (!isRR() && picnum == FIREEXT) + { + movefireext(i); + } + + else if (picnum == pPick(OOZFILTER) || picnum == pPick(SEENINE) || picnum == pPick(SEENINEDEAD) || picnum == (pPick(SEENINEDEAD) + 1)) + { + moveooz(i); + } + + else if (picnum == MASTERSWITCH) + { + movemasterswitch(i); + } + + else if (!isRR() && (picnum == VIEWSCREEN || picnum == VIEWSCREEN2)) + { + moveviewscreen(i); + } + + else if (picnum == pPick(TRASH)) + { + movetrash(i); + } + + else if (!isRR() && picnum >= SIDEBOLT1 && picnum <= SIDEBOLT1 + 3) + { + movesidebolt(i); + } + + else if (picnum >= pPick(BOLT1) && picnum <= pPick(BOLT1) + 3) + { + movebolt(i); + } + + else if (picnum == pPick(WATERDRIP)) + { + movewaterdrip(i); + } + + else if (picnum == pPick(DOORSHOCK)) + { + movedoorshock(i); + } + + else if (picnum == TOUCHPLATE) + { + movetouchplate(i); + } + + else if (isRR() ? picnum == RR_CANWITHSOMETHING : isIn(picnum, CANWITHSOMETHING, CANWITHSOMETHING2, CANWITHSOMETHING3, CANWITHSOMETHING4)) + { + movecanwithsomething(i); + } + + else if (!isRR() ? + isIn(picnum, + EXPLODINGBARREL, + WOODENHORSE, + HORSEONSIDE, + FLOORFLAME, + FIREBARREL, + FIREVASE, + NUKEBARREL, + NUKEBARRELDENTED, + NUKEBARRELLEAKED, + TOILETWATER, + RUBBERCAN, + STEAM, + CEILINGSTEAM, + WATERBUBBLEMAKER) : + isIn(picnum, + RR_1187, + RR_1196, + RR_1251, + RR_1268, + RR_1304, + RR_1305, + RR_1306, + RR_1315, + RR_1317, + RR_1388, + RR_STEAM, + RR_CEILINGSTEAM, + RR_WATERBUBBLEMAKER) + ) + { + int x; + int p = findplayer(s, &x); + execute(i, p, x); + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void bounce(int i) +{ + int k, l, daang, dax, day, daz, xvect, yvect, zvect; + short hitsect; + spritetype* s = &sprite[i]; + + xvect = mulscale10(s->xvel, sintable[(s->ang + 512) & 2047]); + yvect = mulscale10(s->xvel, sintable[s->ang & 2047]); + zvect = s->zvel; + + hitsect = s->sectnum; + + k = sector[hitsect].wallptr; l = wall[k].point2; + daang = getangle(wall[l].x - wall[k].x, wall[l].y - wall[k].y); + + if (s->z < (hittype[i].floorz + hittype[i].ceilingz) >> 1) + k = sector[hitsect].ceilingheinum; + else + k = sector[hitsect].floorheinum; + + dax = mulscale14(k, sintable[(daang) & 2047]); + day = mulscale14(k, sintable[(daang + 1536) & 2047]); + daz = 4096; + + k = xvect * dax + yvect * day + zvect * daz; + l = dax * dax + day * day + daz * daz; + if ((abs(k) >> 14) < l) + { + k = divscale17(k, l); + xvect -= mulscale16(dax, k); + yvect -= mulscale16(day, k); + zvect -= mulscale16(daz, k); + } + + s->zvel = zvect; + s->xvel = ksqrt(dmulscale8(xvect, xvect, yvect, yvect)); + s->ang = getangle(xvect, yvect); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movetongue(int i) +{ + spritetype* s = &sprite[i]; + + hittype[i].temp_data[0] = sintable[(hittype[i].temp_data[1]) & 2047] >> 9; + hittype[i].temp_data[1] += 32; + if (hittype[i].temp_data[1] > 2047) + { + deletesprite(i); + return; + } + + if (sprite[s->owner].statnum == MAXSTATUS) + if (badguy(&sprite[s->owner]) == 0) + { + deletesprite(i); + return; + } + + s->ang = sprite[s->owner].ang; + s->x = sprite[s->owner].x; + s->y = sprite[s->owner].y; + if (sprite[s->owner].picnum == APLAYER) + s->z = sprite[s->owner].z - (34 << 8); + for (int k = 0; k < hittype[i].temp_data[0]; k++) + { + int q = EGS(s->sectnum, + s->x + ((k * sintable[(s->ang + 512) & 2047]) >> 9), + s->y + ((k * sintable[s->ang & 2047]) >> 9), + s->z + ((k * ksgn(s->zvel)) * abs(s->zvel / 12)), pPick(TONGUE), -40 + (k << 1), + 8, 8, 0, 0, 0, i, 5); + sprite[q].cstat = 128; + sprite[q].pal = 8; + } + int k = hittype[i].temp_data[0]; // do not depend on the above loop counter. + int q = EGS(s->sectnum, + s->x + ((k * sintable[(s->ang + 512) & 2047]) >> 9), + s->y + ((k * sintable[s->ang & 2047]) >> 9), + s->z + ((k * ksgn(s->zvel)) * abs(s->zvel / 12)), pPick(INNERJAW), -40, + 32, 32, 0, 0, 0, i, 5); + sprite[q].cstat = 128; + if (hittype[i].temp_data[1] > 512 && hittype[i].temp_data[1] < (1024)) + sprite[q].picnum = pPick(INNERJAW) + 1; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void moveweapons(void) +{ + int j, k, nexti, p, q, tempsect; + int dax, day, daz, x, l, ll, x1, y1; + unsigned int qq; + spritetype* s; + + for (int i = headspritestat[STAT_PROJECTILE]; i >= 0; i = nexti) + { + nexti = nextspritestat[i]; + s = &sprite[i]; + int picnum = picnum; + + if (s->sectnum < 0) + { + deletesprite(i); + continue; + } + + hittype[i].bposx = s->x; + hittype[i].bposy = s->y; + hittype[i].bposz = s->z; + + if (picnum == pPick(RADIUSEXPLOSION) || (!isRR() && picnum == KNEE)) + { + deletesprite(i); + } + + else if (picnum == pPick(TONGUE)) + { + movetongue(i); + } + + else if (picnum == pPick2(FREEZEBLAST, RR_ALIENBLAST) && (s->yvel < 1 || s->extra < 2 || (s->xvel | s->zvel) == 0)) + { + j = spawn(i, pPick(TRANSPORTERSTAR)); + sprite[j].pal = 1; + sprite[j].xrepeat = 32; + sprite[j].yrepeat = 32; + deletesprite(i); + continue; + } + + else if (!isRR() ? + (isIn(picnum, FREEZEBLAST, SHRINKSPARK, RPG, FIRELASER, SPIT, COOLEXPLOSION1) || (isWorldTour() && picnum == FIREBALL)) : + (isIn(picnum, RR_ALIENBLAST, RR_CROSSBOW, RR_FIRELASER, RR_SHITBALL, RR_CIRCLESAW, RR_UWHIP, RR_OWHIP, RR_DILDO) || (isRRRA() && isIn(picnum, RR_CHIKENCROSSBOW, RR_1790))) + ) + { + if (!isRR() && picnum == COOLEXPLOSION1) + if (!S_CheckSoundPlaying(i, WIERDSHOT_FLY)) + A_PlaySound(WIERDSHOT_FLY, i); + + p = -1; + + if ((picnum == pPick2(RPG, RR_CROSSBOW) || (isRRRA() && picnum == RR_CHIKENCROSSBOW)) && sector[s->sectnum].lotag == 2) + { + k = s->xvel >> 1; + ll = s->zvel >> 1; + } + else + { + k = s->xvel; + ll = s->zvel; + } + + dax = s->x; day = s->y; daz = s->z; + + getglobalz(i); + qq = CLIPMASK1; + + if (picnum == pPick2(RPG, RR_CROSSBOW)) + { + if (hittype[i].picnum != pPick(BOSS2) && s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) + { + j = spawn(i, pPick(SMALLSMOKE)); + sprite[j].z += (1 << 8); + } + } + else if (isRRRA() && picnum == RR_CHIKENCROSSBOW) + { + s->hitag++; + if (hittype[i].picnum != RR_BOSS2 && s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) + { + j = spawn(i, RR_SMALLSMOKE); + sprite[j].z += (1 << 8); + if ((krand() & 15) == 2) + { + j = spawn(i, RR_1310); + } + } + if (sprite[s->lotag].extra <= 0) + s->lotag = 0; + if (s->lotag != 0 && s->hitag > 5) + { + spritetype* ts; + int ang, ang2, ang3; + ts = &sprite[s->lotag]; + ang = getangle(ts->x - s->x, ts->y - s->y); + ang2 = ang - s->ang; + ang3 = abs(ang2); + if (ang2 < 100) + { + if (ang3 > 1023) + s->ang += 51; + else + s->ang -= 51; + } + else if (ang2 > 100) + { + if (ang3 > 1023) + s->ang -= 51; + else + s->ang += 51; + } + else + s->ang = ang; + + if (s->hitag > 180) + if (s->zvel <= 0) + s->zvel += 200; + } + } + else if (isRRRA() && picnum == RR_1790) + { + if (s->extra) + { + s->zvel = -(s->extra * 250); + s->extra--; + } + else + makeitfall(i); + if (s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) + { + j = spawn(i, RR_SMALLSMOKE); + sprite[j].z += (1 << 8); + } + } + else if (isWorldTour() && picnum == FIREBALL) + { + if (sector[s->sectnum].lotag == 2) + { + deletesprite(i); + continue; + } + + if (sprite[s->owner].picnum != FIREBALL) + { + if (hittype[i].temp_data[0] >= 1 && hittype[i].temp_data[0] < 6) + { + float siz = 1.0f - (hittype[i].temp_data[0] * 0.2f); + int trail = hittype[i].temp_data[1]; + j = hittype[i].temp_data[1] = spawn(i, FIREBALL); + + auto spr = &sprite[j]; + spr->xvel = sprite[i].xvel; + spr->yvel = sprite[i].yvel; + spr->zvel = sprite[i].zvel; + if (hittype[i].temp_data[0] > 1) + { + FireProj* proj = fire.CheckKey(trail); + if (proj != nullptr) + { + spr->x = proj->x; + spr->y = proj->y; + spr->z = proj->z; + spr->xvel = proj->xv; + spr->yvel = proj->yv; + spr->zvel = proj->zv; + } + } + spr->yrepeat = spr->xrepeat = (short)(sprite[i].xrepeat * siz); + spr->cstat = sprite[i].cstat; + spr->extra = 0; + + FireProj proj = { spr->x, spr->y, spr->z, spr->xvel, spr->yvel, spr->zvel }; + fire.Insert(j, proj); + changespritestat((short)j, (short)4); + } + hittype[i].temp_data[0]++; + } + + if (s->zvel < 15000) + s->zvel += 200; + } + + j = movesprite(i, + (k * (sintable[(s->ang + 512) & 2047])) >> 14, + (k * (sintable[s->ang & 2047])) >> 14, ll, qq); + + if ((picnum == pPick2(RPG, RR_CROSSBOW) || (isRRRA() && isIn(picnum, RR_CHIKENCROSSBOW, RR_1790))) && s->yvel >= 0) + if (FindDistance2D(s->x - sprite[s->yvel].x, s->y - sprite[s->yvel].y) < 256) + j = 49152 | s->yvel; + + if (s->sectnum < 0) // || (isRR() && sector[s->sectnum].filler == 800)) + { + deletesprite(i); + continue; + } + + if ((j & 49152) != 49152) + if (picnum != pPick2(FREEZEBLAST, RR_ALIENBLAST)) + { + if (s->z < hittype[i].ceilingz) + { + j = 16384 | (s->sectnum); + s->zvel = -1; + } + else + if ((s->z > hittype[i].floorz && sector[s->sectnum].lotag != 1) || + (s->z > hittype[i].floorz + (16 << 8) && sector[s->sectnum].lotag == 1)) + { + j = 16384 | (s->sectnum); + if (sector[s->sectnum].lotag != 1) + s->zvel = 1; + } + } + + if (picnum == pPick(FIRELASER)) + { + for (k = -3; k < 2; k++) + { + x = EGS(s->sectnum, + s->x + ((k * sintable[(s->ang + 512) & 2047]) >> 9), + s->y + ((k * sintable[s->ang & 2047]) >> 9), + s->z + ((k * ksgn(s->zvel)) * klabs(s->zvel / 24)), pPick(FIRELASER), -40 + (k << 2), + s->xrepeat, s->yrepeat, 0, 0, 0, s->owner, 5); + + sprite[x].cstat = 128; + sprite[x].pal = s->pal; + } + } + else if (picnum == pPick2(SPIT, RR_SHITBALL)) if (s->zvel < 6144) + s->zvel += gc - 112; + + if (j != 0) + { + if (!isRR() && picnum == COOLEXPLOSION1) + { + if ((j & 49152) == 49152 && sprite[j & (MAXSPRITES - 1)].picnum != APLAYER) + { + continue; + } + s->xvel = 0; + s->zvel = 0; + } + + //if ((j & kHitTypeMask) == kHitSprite) j &= kHitIndexMask; reminder for later. + if ((j & 49152) == 49152) + { + j &= (MAXSPRITES - 1); + + if (isRRRA()) + { + if (sprite[j].picnum == RR_MINION + && (picnum == RR_CROSSBOW || picnum == RR_CHIKENCROSSBOW) + && sprite[j].pal == 19) + { + spritesound(RPG_EXPLODE, i); + j = spawn(i, RR_EXPLOSION2); + sprite[j].x = s->x; + sprite[j].y = s->y; + sprite[j].z = s->z; + continue; + } + } + else if (picnum == pPick2(FREEZEBLAST, RR_ALIENBLAST) && sprite[j].pal == 1) + if (badguy(&sprite[j]) || sprite[j].picnum == APLAYER) + { + j = spawn(i, pPick(TRANSPORTERSTAR)); + sprite[j].pal = 1; + sprite[j].xrepeat = 32; + sprite[j].yrepeat = 32; + + deletesprite(i); + continue; + } + + checkhitsprite(j, i); + + if (sprite[j].picnum == APLAYER) + { + p = sprite[j].yvel; + spritesound(PISTOL_BODYHIT, j); + + if (picnum == pPick2(SPIT, RR_SHITBALL)) + { + if (sprite[s->owner].picnum == RR_MAMAJACKOLOPE) + { + guts(s, RR_RABBITJIBA, 2, myconnectindex); + guts(s, RR_RABBITJIBB, 2, myconnectindex); + guts(s, RR_RABBITJIBC, 2, myconnectindex); + } + + ps[p].q16horiz += 32 << FRACBITS; + ps[p].return_to_center = 8; + + if (ps[p].loogcnt == 0) + { + if (!A_CheckSoundPlaying(ps[p].i, DUKE_LONGTERM_PAIN)) + A_PlaySound(DUKE_LONGTERM_PAIN, ps[p].i); + + j = 3 + (krand() & 3); + ps[p].numloogs = j; + ps[p].loogcnt = 24 * 4; + for (x = 0; x < j; x++) + { + ps[p].loogiex[x] = krand() % xdim; + ps[p].loogiey[x] = krand() % ydim; + } + } + } + } + } + else if ((j & 49152) == 32768) + { + j &= (MAXWALLS - 1); + + if (isRRRA() && sprite[s->owner].picnum == RR_MAMAJACKOLOPE) + { + guts(s, RR_RABBITJIBA, 2, myconnectindex); + guts(s, RR_RABBITJIBB, 2, myconnectindex); + guts(s, RR_RABBITJIBC, 2, myconnectindex); + } + + bool ismirror = (wall[j].overpicnum == pPick(MIRROR) || wall[j].picnum == pPick(MIRROR)); + if (ismirror && !isRR() ? + isIn(picnum, RPG, FREEZEBLAST, SPIT) : + (isIn(picnum, RR_CROSSBOW, RR_ALIENBLAST, RR_SHITBALL, RR_CIRCLESAW) || (isRRRA() && picnum == RR_CHIKENCROSSBOW)) + ) + { + 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; + s->owner = i; + spawn(i, pPick(TRANSPORTERSTAR)); + continue; + } + else + { + setsprite(i, dax, day, daz); + checkhitwall(i, j, s->x, s->y, s->z, picnum); + + if (!isRRRA() && picnum == pPick2(FREEZEBLAST, RR_ALIENBLAST)) + { + if (!ismirror) + { + s->extra >>= 1; + s->yvel--; + } + + 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; + continue; + } + + if (isRR() && s->picnum == RR_CIRCLESAW) + { + if (wall[j].picnum >= RR_3643 && wall[j].picnum < RR_3643 + 3) + { + deletesprite(i); + } + if (s->extra <= 0) + { + s->x += sintable[(s->ang + 512) & 2047] >> 7; + s->y += sintable[s->ang & 2047] >> 7; + if (!isRRRA() || (sprite[s->owner].picnum != RR_DAISYMAE && sprite[s->owner].picnum != RR_DAISYMAESTAYPUT)) + { + j = spawn(i, RR_CIRCLESTUCK); + sprite[j].xrepeat = 8; + sprite[j].yrepeat = 8; + sprite[j].cstat = 16; + sprite[j].ang = (sprite[j].ang + 512) & 2047; + sprite[j].clipdist = mulscale7(s->xrepeat, tilesiz[s->picnum].x); + } + deletesprite(i); + continue; + } + if (!ismirror) + { + s->extra -= 20; + s->yvel--; + } + + 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; + continue; + } + } + } + else if ((j & 49152) == 16384) + { + setsprite(i, dax, day, daz); + + if (isRRRA() && sprite[s->owner].picnum == RR_MAMAJACKOLOPE) + { + guts(s, RR_RABBITJIBA, 2, myconnectindex); + guts(s, RR_RABBITJIBB, 2, myconnectindex); + guts(s, RR_RABBITJIBC, 2, myconnectindex); + } + + if (s->zvel < 0) + { + if (sector[s->sectnum].ceilingstat & 1) + if (sector[s->sectnum].ceilingpal == 0) + { + deletesprite(i); + continue; + } + + checkhitceiling(s->sectnum); + } + + if (!isRRRA() && picnum == pPick2(FREEZEBLAST, RR_ALIENBLAST)) + { + bounce(i); + ssp(i, qq); + s->extra >>= 1; + if (s->xrepeat > 8) + s->xrepeat -= 2; + if (s->yrepeat > 8) + s->yrepeat -= 2; + s->yvel--; + continue; + } + } + + if (picnum != pPick2(SPIT, RR_SHITBALL)) + { + if (picnum == pPick2(RPG, RR_CROSSBOW)) + { + k = spawn(i, pPick(EXPLOSION2)); + sprite[k].x = dax; + sprite[k].y = day; + sprite[k].z = daz; + + if (s->xrepeat < 10) + { + sprite[k].xrepeat = 6; + sprite[k].yrepeat = 6; + } + else if ((j & 49152) == 16384) + { + if (!isRR() && s->zvel > 0) + spawn(i, EXPLOSION2BOT); + else { sprite[k].cstat |= 8; sprite[k].z += (48 << 8); } + } + } + else if (isRRRA() && s->picnum == RR_CHIKENCROSSBOW) + { + k = spawn(i, RR_EXPLOSION2); + sprite[k].x = dax; + sprite[k].y = day; + sprite[k].z = daz; + + if (s->xrepeat < 10) + { + sprite[k].xrepeat = 6; + sprite[k].yrepeat = 6; + } + else if ((j & 49152) == 16384) + { + sprite[k].cstat |= 8; + sprite[k].z += (48 << 8); + } + } + else if (isRRRA() && s->picnum == RR_1790) + { + s->extra = 160; + k = spawn(i, RR_EXPLOSION2); + sprite[k].x = dax; + sprite[k].y = day; + sprite[k].z = daz; + + if (s->xrepeat < 10) + { + sprite[k].xrepeat = 6; + sprite[k].yrepeat = 6; + } + else if ((j & 49152) == 16384) + { + sprite[k].cstat |= 8; + sprite[k].z += (48 << 8); + } + } + + else if (!isRR() && picnum == SHRINKSPARK) + { + spawn(i, SHRINKEREXPLOSION); + spritesound(SHRINKER_HIT, i); + hitradius(i, shrinkerblastradius, 0, 0, 0, 0); + } + else if (!isRR() ? + !isIn(picnum, COOLEXPLOSION1, FREEZEBLAST, FIRELASER) : + !isIn(picnum, RR_ALIENBLAST, RR_FIRELASER, RR_CIRCLESAW)) + { + k = spawn(i, pPick(EXPLOSION2)); + sprite[k].xrepeat = sprite[k].yrepeat = s->xrepeat >> 1; + if ((j & 49152) == 16384) + { + if (s->zvel < 0) + { + sprite[k].cstat |= 8; sprite[k].z += (72 << 8); + } + } + } + if (picnum == pPick2(RPG, RR_CROSSBOW)) + { + spritesound(RPG_EXPLODE, i); + + if (s->xrepeat >= 10) + { + x = s->extra; + hitradius(i, rpgblastradius, x >> 2, x >> 1, x - (x >> 2), x); + } + else + { + x = s->extra + (global_random & 3); + hitradius(i, (rpgblastradius >> 1), x >> 2, x >> 1, x - (x >> 2), x); + } + } + else if (isRRRA() && s->picnum == RR_CHIKENCROSSBOW) + { + s->extra = 150; + spritesound(247, i); + + if (s->xrepeat >= 10) + { + x = s->extra; + hitradius(i, rpgblastradius, x >> 2, x >> 1, x - (x >> 2), x); + } + else + { + x = s->extra + (global_random & 3); + hitradius(i, (rpgblastradius >> 1), x >> 2, x >> 1, x - (x >> 2), x); + } + } + else if (s->picnum == RR_1790) + { + s->extra = 160; + spritesound(RPG_EXPLODE, i); + + if (s->xrepeat >= 10) + { + x = s->extra; + hitradius(i, rpgblastradius, x >> 2, x >> 1, x - (x >> 2), x); + } + else + { + x = s->extra + (global_random & 3); + hitradius(i, (rpgblastradius >> 1), x >> 2, x >> 1, x - (x >> 2), x); + } + } + + } + if (isRR() || picnum != COOLEXPLOSION1) + { + deletesprite(i); + continue; + } + } + if (!isRR() && picnum == COOLEXPLOSION1) + { + s->shade++; + if (s->shade >= 40) + { + deletesprite(i); + continue; + } + } + else if ((picnum == pPick2(RPG, RR_CROSSBOW) || (isRRRA() && picnum == RR_CHIKENCROSSBOW)) && sector[s->sectnum].lotag == 2 && s->xrepeat >= 10 && rnd(140)) + spawn(i, pPick(WATERBUBBLE)); + + continue; + } + else if (picnum == pPick(SHOTSPARK1)) + { + p = findplayer(s, &x); + execute(i, p, x); + } + } +} + + + +END_DUKE_NS diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp new file mode 100644 index 000000000..2d0f547d0 --- /dev/null +++ b/source/games/duke/src/actors_r.cpp @@ -0,0 +1,3667 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment +Copyright (C) 2000, 2003 - Matt Saettler (EDuke Enhancements) +Copyright (C) 2017-2019 - Nuke.YKT +Copyright (C) 2020 - Christoph Oelckers + +This file is part of Enhanced Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms + +EDuke enhancements integrated: 04/13/2003 - Matt Saettler + +Note: EDuke source was in transition. Changes are in-progress in the +source as it is released. + +This file is a combination of code from the following sources: +- EDuke 2 by Matt Saettler +- JFDuke by Jonathon Fowler (jf@jonof.id.au), +- DukeGDX and RedneckGDX by Alexander Makarov-[M210] (m210-2007@mail.ru) +- Redneck Rampage reconstructed source by Nuke.YKT + +*/ +//------------------------------------------------------------------------- + +#include "ns.h" +#include "global.h" +#include "names.h" + +BEGIN_DUKE_NS + +struct FireProj +{ + int x, y, z; + int xv, yv, zv; +}; + +static TMap fire; + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +bool ceilingspace(int sectnum) +{ + if ((sector[sectnum].ceilingstat & 1) && sector[sectnum].ceilingpal == 0) + { + switch (sector[sectnum].ceilingpicnum) + { + case MOONSKY1: + case BIGORBIT1: + return !isRR(); + + case RR_MOONSKY1: + case RR_BIGORBIT1: + return isRR(); + } + } + return 0; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +bool floorspace(int sectnum) +{ + if ((sector[sectnum].floorstat & 1) && sector[sectnum].ceilingpal == 0) + { + switch (sector[sectnum].floorpicnum) + { + case MOONSKY1: + case BIGORBIT1: + return !isRR(); + + case RR_MOONSKY1: + case RR_BIGORBIT1: + return !!isRR(); + } + } + return 0; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void addammo(short weapon, struct player_struct* p, short amount) +{ + p->ammo_amount[weapon] += amount; + + if (p->ammo_amount[weapon] > max_ammo_amount[weapon]) + p->ammo_amount[weapon] = max_ammo_amount[weapon]; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void addweapon(struct player_struct* p, int weapon) +{ + short cw = p->curr_weapon; + if (p->OnMotorcycle || p->OnBoat) + { + p->gotweapon.Set(weapon); + if (weapon == SHRINKER_WEAPON) + { + p->gotweapon.Set(GROW_WEAPON); + p->ammo_amount[GROW_WEAPON] = 1; + } + else if (weapon == RPG_WEAPON) + { + p->gotweapon.Set(RA16_WEAPON); + } + else if (weapon == RA15_WEAPON) + { + p->ammo_amount[RA15_WEAPON] = 1; + } + return; + } + + if (p->gotweapon[weapon] == 0) + { + p->gotweapon.Set(weapon); + if (weapon == SHRINKER_WEAPON) + { + p->gotweapon.Set(GROW_WEAPON); + if (isRRRA()) p->ammo_amount[GROW_WEAPON] = 1; + } + if (isRRRA()) + { + if (weapon == RPG_WEAPON) + { + p->gotweapon.Set(RA16_WEAPON); + } + if (weapon == RA15_WEAPON) + { + p->ammo_amount[RA15_WEAPON] = 50; + } + } + + if (!isRR() || weapon != HANDBOMB_WEAPON) + cw = weapon; + } + else + cw = weapon; + + if (isRR() && weapon == HANDBOMB_WEAPON) + p->last_weapon = -1; + + p->random_club_frame = 0; + + if (p->holster_weapon == 0) + { + p->weapon_pos = -1; + p->last_weapon = p->curr_weapon; + } + else + { + p->weapon_pos = 10; + p->holster_weapon = 0; + p->last_weapon = -1; + } + + p->kickback_pic = 0; +#ifdef EDUKE + if (p->curr_weapon != cw) + { + short snum; + snum = sprite[p->i].yvel; + + SetGameVarID(g_iWeaponVarID, cw, p->i, snum); + if (p->curr_weapon >= 0) + { + SetGameVarID(g_iWorksLikeVarID, aplWeaponWorksLike[weapon][snum], p->i, snum); + } + else + { + SetGameVarID(g_iWorksLikeVarID, -1, p->i, snum); + } + SetGameVarID(g_iReturnVarID, 0, -1, snum); + OnEvent(EVENT_CHANGEWEAPON, p->i, snum, -1); + if (GetGameVarID(g_iReturnVarID, -1, snum) == 0) + { + p->curr_weapon = cw; + } + } +#else + p->curr_weapon = cw; +#endif + + switch (weapon) + { + case RA15_WEAPON: + case KNEE_WEAPON: + case TRIPBOMB_WEAPON: + case HANDREMOTE_WEAPON: + case HANDBOMB_WEAPON: + break; + case SHOTGUN_WEAPON: + spritesound(SHOTGUN_COCK, p->i); + break; + case PISTOL_WEAPON: + spritesound(INSERT_CLIP, p->i); + break; + default: + spritesound(SELECT_WEAPON, p->i); + break; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void checkavailinven(struct player_struct* p) +{ + + if (p->firstaid_amount > 0) + p->inven_icon = ICON_FIRSTAID; + else if (p->steroids_amount > 0) + p->inven_icon = ICON_STEROIDS; + else if (p->holoduke_amount > 0) + p->inven_icon = ICON_HOLODUKE; + else if (p->jetpack_amount > 0) + p->inven_icon = ICON_JETPACK; + else if (p->heat_amount > 0) + p->inven_icon = ICON_HEATS; + else if (p->scuba_amount > 0) + p->inven_icon = ICON_SCUBA; + else if (p->boot_amount > 0) + p->inven_icon = ICON_BOOTS; + else p->inven_icon = ICON_NONE; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void checkavailweapon(struct player_struct* p) +{ + short i, snum; + int weap; + + if (p->wantweaponfire >= 0) + { + weap = p->wantweaponfire; + p->wantweaponfire = -1; + + if (weap == p->curr_weapon) return; + else if (p->gotweapon[weap] && p->ammo_amount[weap] > 0) + { + addweapon(p, weap); + return; + } + } + + weap = p->curr_weapon; + if (p->gotweapon[weap] && p->ammo_amount[weap] > 0) + return; + + snum = sprite[p->i].yvel; + + // Note: RedNukem has this restriction, but the original source and RedneckGDX do not. +#if 1 // TRANSITIONAL + int max = ((isRR()) ? DEVISTATOR_WEAPON : FREEZE_WEAPON); +#else + int max = FREEZE_WEAPON; +#endif + for (i = 0; i < 10; i++) + { + weap = ud.wchoice[snum][i]; + if ((g_gameType & GAMEFLAG_SHAREWARE) && weap > 6) continue; + + if (weap == 0) weap = max; + else weap--; + + if (weap == KNEE_WEAPON || (p->gotweapon[weap] && p->ammo_amount[weap] > 0)) + break; + } + + if (i == HANDREMOTE_WEAPON) weap = KNEE_WEAPON; + + // Found the weapon + + p->last_weapon = p->curr_weapon; + p->random_club_frame = 0; + p->curr_weapon = weap; + if (isWW2GI()) + { + SetGameVarID(g_iWeaponVarID, p->curr_weapon, p->i, snum); + if (p->curr_weapon >= 0) + { + SetGameVarID(g_iWorksLikeVarID, aplWeaponWorksLike[p->curr_weapon][snum], p->i, snum); + } + else + { + SetGameVarID(g_iWorksLikeVarID, -1, p->i, snum); + } + OnEvent(EVENT_CHANGEWEAPON, p->i, snum, -1); + } + + p->kickback_pic = 0; + if (p->holster_weapon == 1) + { + p->holster_weapon = 0; + p->weapon_pos = 10; + } + else p->weapon_pos = -1; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +bool ifsquished(int i, int p) +{ + if (isRR()) return false; // this function is a no-op in RR's source. + + bool squishme = false; + if (sprite[i].picnum == TILE_APLAYER && ud.clipping) + return false; + + auto& sc = sector[sprite[i].sectnum]; + int floorceildist = sc.floorz - sc.ceilingz; + + if (sc.lotag != ST_23_SWINGING_DOOR) + { + if (sprite[i].pal == 1) + squishme = floorceildist < (32 << 8) && (sc.lotag & 32768) == 0; + else + squishme = floorceildist < (12 << 8); + } + + if (squishme) + { + FTA(QUOTE_SQUISHED, &ps[p]); + + if (badguy(&sprite[i])) + sprite[i].xvel = 0; + + if (sprite[i].pal == 1) + { + hittype[i].picnum = SHOTSPARK1; + hittype[i].extra = 1; + return false; + } + + return true; + } + return false; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void clearcamera(player_struct* ps) +{ + ps->newowner = -1; + ps->posx = ps->oposx; + ps->posy = ps->oposy; + ps->posz = ps->oposz; + ps->q16ang = ps->oq16ang; + updatesector(ps->posx, ps->posy, &ps->cursectnum); + setpal(ps); + + int k = headspritestat[1]; + while (k >= 0) + { + if (sprite[k].picnum == CAMERA1) + sprite[k].yvel = 0; + k = nextspritestat[k]; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void hitradius(short i, int r, int hp1, int hp2, int hp3, int hp4) +{ + spritetype* s, * sj; + walltype* wal; + int d, q, x1, y1; + int sectcnt, sectend, dasect, startwall, endwall, nextsect; + short j, p, x, nextj, sect; + static const uint8_t statlist[] = { STAT_DEFAULT, STAT_ACTOR, STAT_STANDABLE, STAT_PLAYER, STAT_FALLER, STAT_ZOMBIEACTOR, STAT_MISC }; + short tempshort[MAXSECTORS]; // originally hijacked a global buffer which is bad. Q: How many do we really need? RedNukem says 64. + + s = &sprite[i]; + + if (s->xrepeat < 11) + { + if (!isRR()) + { + if (s->picnum == RPG) goto SKIPWALLCHECK; + } + else + { + if (s->picnum == RR_CROSSBOW || ((isRRRA()) && s->picnum == RR_CHIKENCROSSBOW)) goto SKIPWALLCHECK; + } + } + + if ((isRR()) || s->picnum != SHRINKSPARK) + { + tempshort[0] = s->sectnum; + dasect = s->sectnum; + sectcnt = 0; sectend = 1; + + do + { + dasect = tempshort[sectcnt++]; + if (((sector[dasect].ceilingz - s->z) >> 8) < r) + { + d = abs(wall[sector[dasect].wallptr].x - s->x) + abs(wall[sector[dasect].wallptr].y - s->y); + if (d < r) + checkhitceiling(dasect); + else + { + // ouch... + d = abs(wall[wall[wall[sector[dasect].wallptr].point2].point2].x - s->x) + abs(wall[wall[wall[sector[dasect].wallptr].point2].point2].y - s->y); + if (d < r) + checkhitceiling(dasect); + } + } + + startwall = sector[dasect].wallptr; + endwall = startwall + sector[dasect].wallnum; + for (x = startwall, wal = &wall[startwall]; x < endwall; x++, wal++) + if ((abs(wal->x - s->x) + abs(wal->y - s->y)) < r) + { + nextsect = wal->nextsector; + if (nextsect >= 0) + { + for (dasect = sectend - 1; dasect >= 0; dasect--) + if (tempshort[dasect] == nextsect) break; + if (dasect < 0) tempshort[sectend++] = nextsect; + } + x1 = (((wal->x + wall[wal->point2].x) >> 1) + s->x) >> 1; + y1 = (((wal->y + wall[wal->point2].y) >> 1) + s->y) >> 1; + updatesector(x1, y1, §); + if (sect >= 0 && cansee(x1, y1, s->z, sect, s->x, s->y, s->z, s->sectnum)) + checkhitwall(i, x, wal->x, wal->y, s->z, s->picnum); + } + } while (sectcnt < sectend); + } + +SKIPWALLCHECK: + + int val = (isRR()) ? 24 : 16; + q = -(val << 8) + (krand() & ((32 << 8) - 1)); + + for (x = 0; x < 7; x++) + { + j = headspritestat[statlist[x]]; + while (j >= 0) + { + nextj = nextspritestat[j]; + sj = &sprite[j]; + + if (isWorldTour()) + { + if (sprite[s->owner].picnum == APLAYER && sj->picnum == APLAYER && ud.coop != 0 && ud.ffire == 0 && s->owner != j) + continue; + + if (s->picnum == FLAMETHROWERFLAME && ((sprite[s->owner].picnum == FIREFLY && sj->picnum == FIREFLY) || (sprite[s->owner].picnum == BOSS5 && sj->picnum == BOSS5))) + continue; + } + + if (x == 0 || x >= 5 || AFLAMABLE(sj->picnum)) + { + if ((!isRR() && s->picnum != SHRINKSPARK) || (sj->cstat & 257)) + if (dist(s, sj) < r) + { + if (badguy(sj) && !cansee(sj->x, sj->y, sj->z + q, sj->sectnum, s->x, s->y, s->z + q, s->sectnum)) + goto BOLT; + checkhitsprite(j, i); + } + } + else if (!isRR()) + { + if (sj->extra >= 0 && sj != s && (sj->picnum == TRIPBOMB || badguy(sj) || sj->picnum == QUEBALL || sj->picnum == STRIPEBALL || (sj->cstat & 257) || sj->picnum == DUKELYINGDEAD)) + { + if (s->picnum == SHRINKSPARK && sj->picnum != SHARK && (j == s->owner || sj->xrepeat < 24)) + { + j = nextj; + continue; + } + if (s->picnum == MORTER && j == s->owner) + { + j = nextj; + continue; + } + + if (sj->picnum == APLAYER) sj->z -= PHEIGHT; + d = dist(s, sj); + if (sj->picnum == APLAYER) sj->z += PHEIGHT; + + if (d < r && cansee(sj->x, sj->y, sj->z - (8 << 8), sj->sectnum, s->x, s->y, s->z - (12 << 8), s->sectnum)) + { + hittype[j].ang = getangle(sj->x - s->x, sj->y - s->y); + + if (s->picnum == RPG && sj->extra > 0) + hittype[j].picnum = RPG; + else if (!isWorldTour()) + { + if (s->picnum == SHRINKSPARK) + hittype[j].picnum = SHRINKSPARK; + else hittype[j].picnum = RADIUSEXPLOSION; + } + else + { + if (s->picnum == SHRINKSPARK || s->picnum == FLAMETHROWERFLAME) + hittype[j].picnum = s->picnum; + else if (s->picnum != FIREBALL || sprite[s->owner].picnum != APLAYER) + { + if (s->picnum == LAVAPOOL) + hittype[j].picnum = FLAMETHROWERFLAME; + else + hittype[j].picnum = RADIUSEXPLOSION; + } + else + hittype[j].picnum = FLAMETHROWERFLAME; + } + + if (s->picnum != SHRINKSPARK && (!isWorldTour() && s->picnum != LAVAPOOL)) + { + if (d < r / 3) + { + if (hp4 == hp3) hp4++; + hittype[j].extra = hp3 + (krand() % (hp4 - hp3)); + } + else if (d < 2 * r / 3) + { + if (hp3 == hp2) hp3++; + hittype[j].extra = hp2 + (krand() % (hp3 - hp2)); + } + else if (d < r) + { + if (hp2 == hp1) hp2++; + hittype[j].extra = hp1 + (krand() % (hp2 - hp1)); + } + + if (sprite[j].picnum != TANK && sprite[j].picnum != ROTATEGUN && sprite[j].picnum != RECON && sprite[j].picnum != BOSS1 && sprite[j].picnum != BOSS2 && sprite[j].picnum != BOSS3 && sprite[j].picnum != BOSS4) + { + if (sj->xvel < 0) sj->xvel = 0; + sj->xvel += (s->extra << 2); + } + + if (sj->picnum == PODFEM1 || sj->picnum == FEM1 || + sj->picnum == FEM2 || sj->picnum == FEM3 || + sj->picnum == FEM4 || sj->picnum == FEM5 || + sj->picnum == FEM6 || sj->picnum == FEM7 || + sj->picnum == FEM8 || sj->picnum == FEM9 || + sj->picnum == FEM10 || sj->picnum == STATUE || + sj->picnum == STATUEFLASH || sj->picnum == SPACEMARINE || sj->picnum == QUEBALL || sj->picnum == STRIPEBALL) + checkhitsprite(j, i); + } + else if (s->extra == 0) hittype[j].extra = 0; + + if (sj->picnum != RADIUSEXPLOSION && + s->owner >= 0 && sprite[s->owner].statnum < MAXSTATUS) + { + if (sj->picnum == APLAYER) + { + p = sj->yvel; + + if (isWorldTour() && hittype[j].picnum == FLAMETHROWERFLAME && sprite[s->owner].picnum == APLAYER) + { + ps[p].numloogs = -1 - s->yvel; + } + + if (ps[p].newowner >= 0) + { + clearcamera(&ps[p]); + } + } + hittype[j].owner = s->owner; + } + } + } + } + else + { + if (sj->extra >= 0 && sj != s && (badguy(sj) || sj->picnum == RR_QUEBALL || sj->picnum == RR_3440 || sj->picnum == RR_STRIPEBALL || (sj->cstat & 257) || sj->picnum == RR_LNRDLYINGDEAD)) + { + if (s->picnum == RR_MORTER && j == s->owner) + { + j = nextj; + continue; + } + if ((isRRRA()) && s->picnum == RR_CHEERBOMB && j == s->owner) + { + j = nextj; + continue; + } + + if (sj->picnum == APLAYER) sj->z -= PHEIGHT; + d = dist(s, sj); + if (sj->picnum == APLAYER) sj->z += PHEIGHT; + + if (d < r && cansee(sj->x, sj->y, sj->z - (8 << 8), sj->sectnum, s->x, s->y, s->z - (12 << 8), s->sectnum)) + { + if ((isRRRA()) && sprite[j].picnum == RR_MINION && sprite[j].pal == 19) + { + j = nextj; + continue; + } + + hittype[j].ang = getangle(sj->x - s->x, sj->y - s->y); + + if (s->picnum == RR_CROSSBOW && sj->extra > 0) + hittype[j].picnum = RR_CROSSBOW; + else if ((isRRRA()) && s->picnum == RR_CHIKENCROSSBOW && sj->extra > 0) + hittype[j].picnum = RR_CROSSBOW; + else + hittype[j].picnum = RR_RADIUSEXPLOSION; + + if (d < r / 3) + { + if (hp4 == hp3) hp4++; + hittype[j].extra = hp3 + (krand() % (hp4 - hp3)); + } + else if (d < 2 * r / 3) + { + if (hp3 == hp2) hp3++; + hittype[j].extra = hp2 + (krand() % (hp3 - hp2)); + } + else if (d < r) + { + if (hp2 == hp1) hp2++; + hittype[j].extra = hp1 + (krand() % (hp2 - hp1)); + } + + int pic = sprite[j].picnum; + if ((isRRRA())? + (pic != RR_HULK && pic != RR_MAMAJACKOLOPE && pic != RR_GUITARBILLY && pic != RR_BANJOCOOTER && pic != RR_MAMACLOUD) : + (pic != RR_HULK && pic != RR_SBMOVE)) + { + if (sprite[j].xvel < 0) sprite[j].xvel = 0; + sprite[j].xvel += (sprite[j].extra << 2); + } + + if (sj->picnum == RR_STATUEFLASH || sj->picnum == RR_QUEBALL || + sj->picnum == RR_STRIPEBALL || sj->picnum == RR_3440) + checkhitsprite(j, i); + + if (sprite[j].picnum != RR_RADIUSEXPLOSION && + s->owner >= 0 && sprite[s->owner].statnum < MAXSTATUS) + { + if (sprite[j].picnum == APLAYER) + { + p = sprite[j].yvel; + if (ps[p].newowner >= 0) + { + clearcamera(&ps[p]); + } + } + hittype[j].owner = s->owner; + } + } + } + } + BOLT: + j = nextj; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +int movesprite(short spritenum, int xchange, int ychange, int zchange, unsigned int cliptype) +{ + int daz, h, oldx, oldy; + short retval, dasectnum, cd; + char bg; + + bg = badguy(&sprite[spritenum]); + + if (sprite[spritenum].statnum == 5 || (bg && sprite[spritenum].xrepeat < 4)) + { + sprite[spritenum].x += (xchange * TICSPERFRAME) >> 2; + sprite[spritenum].y += (ychange * TICSPERFRAME) >> 2; + sprite[spritenum].z += (zchange * TICSPERFRAME) >> 2; + if (bg) + setsprite(spritenum, sprite[spritenum].x, sprite[spritenum].y, sprite[spritenum].z); + return 0; + } + + dasectnum = sprite[spritenum].sectnum; + + daz = sprite[spritenum].z; + h = ((tilesiz[sprite[spritenum].picnum].y * sprite[spritenum].yrepeat) << 1); + daz -= h; + + if (bg) + { + oldx = sprite[spritenum].x; + oldy = sprite[spritenum].y; + + if (sprite[spritenum].xrepeat > 60) + retval = clipmove(&sprite[spritenum].x, &sprite[spritenum].y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 1024L, (4 << 8), (4 << 8), cliptype); + else + { + if (isRR()) + cd = 192; + else if (sprite[spritenum].picnum == LIZMAN) + cd = 292; +#if 0 // TRANSITIONAL the needed infrastructure for this is too different for now + else if ((actortype[sprite[spritenum].picnum] & 3)) +#else + else if (A_CheckSpriteFlags(spritenum, SFLAG_BADGUY)) +#endif + cd = sprite[spritenum].clipdist << 2; + else + cd = 192; + + retval = clipmove(&sprite[spritenum].x, &sprite[spritenum].y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), cd, (4 << 8), (4 << 8), cliptype); + } + + bool rr = (isRR()); + // conditional code from hell... + if (dasectnum < 0 || (dasectnum >= 0 && + ((hittype[spritenum].actorstayput >= 0 && hittype[spritenum].actorstayput != dasectnum) || + (!rr && + ( + ((sprite[spritenum].picnum == BOSS2) && sprite[spritenum].pal == 0 && sector[dasectnum].lotag != 3) || + ((sprite[spritenum].picnum == BOSS1 || sprite[spritenum].picnum == BOSS2) && sector[dasectnum].lotag == ST_1_ABOVE_WATER) || + (sector[dasectnum].lotag == ST_1_ABOVE_WATER && (sprite[spritenum].picnum == LIZMAN || (sprite[spritenum].picnum == LIZTROOP && sprite[spritenum].zvel == 0))) + ) + ) + ))) + { + sprite[spritenum].x = oldx; + sprite[spritenum].y = oldy; + if (sector[dasectnum].lotag == ST_1_ABOVE_WATER && (rr || sprite[spritenum].picnum == LIZMAN)) + sprite[spritenum].ang = (krand() & 2047); + else if ((hittype[spritenum].temp_data[0] & 3) == 1 && (rr || sprite[spritenum].picnum != COMMANDER)) + sprite[spritenum].ang = (krand() & 2047); + setsprite(spritenum, oldx, oldy, sprite[spritenum].z); + if (dasectnum < 0) dasectnum = 0; + return (16384 + dasectnum); + } + if ((retval & 49152) >= 32768 && (hittype[spritenum].cgg == 0)) sprite[spritenum].ang += 768; + } + else + { + if (sprite[spritenum].statnum == 4) + retval = + clipmove(&sprite[spritenum].x, &sprite[spritenum].y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 8L, (4 << 8), (4 << 8), cliptype); + else + retval = + clipmove(&sprite[spritenum].x, &sprite[spritenum].y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), (int)(sprite[spritenum].clipdist << 2), (4 << 8), (4 << 8), cliptype); + } + + if (dasectnum >= 0) + if ((dasectnum != sprite[spritenum].sectnum)) + changespritesect(spritenum, dasectnum); + daz = sprite[spritenum].z + ((zchange * TICSPERFRAME) >> 3); + if ((daz > hittype[spritenum].ceilingz) && (daz <= hittype[spritenum].floorz)) + sprite[spritenum].z = daz; + else + if (retval == 0) + return(16384 + dasectnum); + + return(retval); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +int ssp(short i, unsigned int cliptype) //The set sprite function +{ + spritetype* s; + int movetype; + + s = &sprite[i]; + + movetype = movesprite(i, + (s->xvel * (sintable[(s->ang + 512) & 2047])) >> 14, + (s->xvel * (sintable[s->ang & 2047])) >> 14, s->zvel, + cliptype); + + return (movetype == 0); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void insertspriteq(int i) +{ + if (spriteqamount > 0) + { + if (spriteq[spriteqloc] >= 0) + sprite[spriteq[spriteqloc]].xrepeat = 0; + spriteq[spriteqloc] = i; + spriteqloc = (spriteqloc + 1) % spriteqamount; + } + else sprite[i].xrepeat = sprite[i].yrepeat = 0; +} + +//--------------------------------------------------------------------------- +// +// consolidation of several nearly identical functions +// lotsofmoney -> MONEY / RR_FEATHERS +// lotsofmail -> MAIL +// lotsofpaper -> PAPER +// +//--------------------------------------------------------------------------- + +void lotsofstuff(spritetype* s, short n, int spawntype) +{ + short i, j; + for (i = n; i > 0; i--) + { + short r1 = krand(), r2 = krand(); // using the RANDCORRECT version from RR. + // TRANSITIONAL RedNukem sets the spawner as owner. + j = EGS(s->sectnum, s->x, s->y, s->z - (r2 % (47 << 8)), spawntype, -32, 8, 8, r1 & 2047, 0, 0, 0, 5); + sprite[j].cstat = krand() & 12; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void guts(spritetype* s, short gtype, short n, short p) +{ + int gutz, floorz; + int i=0, j; + int sx, sy; + uint8_t pal; + + if (badguy(s) && s->xrepeat < 16) + sx = sy = 8; + else sx = sy = 32; + + gutz = s->z - (8 << 8); + floorz = getflorzofslope(s->sectnum, s->x, s->y); + + if (gutz > (floorz - (8 << 8))) + gutz = floorz - (8 << 8); + + if (!isRR() && s->picnum == COMMANDER) + gutz -= (24 << 8); + + if (badguy(s) && s->pal == 6) + pal = 6; + else + { + pal = 0; + if (isRRRA()) + { + if (s->picnum == RR_MINION && (s->pal == 8 || s->pal == 19)) pal = s->pal; + } + } + + if (isRR()) + { + sx >>= 1; + sy >>= 1; + } + + for (j = 0; j < n; j++) + { + // RANDCORRECT version from RR. + int a = krand() & 2047; + int r1 = krand(); + int r2 = krand(); + int r3 = krand(); + int r4 = krand(); + int r5 = krand(); + // TRANSITIONAL: owned by a player??? + i = EGS(s->sectnum, s->x + (r5 & 255) - 128, s->y + (r4 & 255) - 128, gutz - (r3 & 8191), gtype, -32, sx, sy, a, 48 + (r2 & 31), -512 - (r1 & 2047), ps[p].i, 5); + if (!isRR() && sprite[i].picnum == JIBS2) + { + sprite[i].xrepeat >>= 2; + sprite[i].yrepeat >>= 2; + } + if (pal != 0) + sprite[i].pal = pal; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void gutsdir(spritetype* s, short gtype, short n, short p) +{ + int gutz, floorz; + short i, j; + char sx, sy; + + if (badguy(s) && s->xrepeat < 16) + sx = sy = 8; + else sx = sy = 32; + + gutz = s->z - (8 << 8); + floorz = getflorzofslope(s->sectnum, s->x, s->y); + + if (gutz > (floorz - (8 << 8))) + gutz = floorz - (8 << 8); + + if (!isRR() && s->picnum == COMMANDER) + gutz -= (24 << 8); + + for (j = 0; j < n; j++) + { + int a = krand() & 2047; + int r1 = krand(); + int r2 = krand(); + // TRANSITIONAL: owned by a player??? + i = EGS(s->sectnum, s->x, s->y, gutz, gtype, -32, sx, sy, a, 256 + (r2 & 127), -512 - (r1 & 2047), ps[p].i, 5); + } +} + +//--------------------------------------------------------------------------- +// +// movesector - why is this in actors.cpp? +// +//--------------------------------------------------------------------------- + +void ms(short i) +{ + //T1,T2 and T3 are used for all the sector moving stuff!!! + + short startwall, endwall, x; + int tx, ty; + spritetype* s; + + s = &sprite[i]; + + s->x += (s->xvel * (sintable[(s->ang + 512) & 2047])) >> 14; + s->y += (s->xvel * (sintable[s->ang & 2047])) >> 14; + + int j = hittype[i].temp_data[1]; + int k = hittype[i].temp_data[2]; + + startwall = sector[s->sectnum].wallptr; + endwall = startwall + sector[s->sectnum].wallnum; + for (x = startwall; x < endwall; x++) + { + rotatepoint( + 0, 0, + msx[j], msy[j], + k & 2047, &tx, &ty); + + dragpoint(x, s->x + tx, s->y + ty); + + j++; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movefta(void) +{ + int x, px, py, sx, sy; + short i, j, p, psect, ssect, nexti; + spritetype* s; + + i = headspritestat[STAT_ZOMBIEACTOR]; + while (i >= 0) + { + nexti = nextspritestat[i]; + + s = &sprite[i]; + p = findplayer(s, &x); + + ssect = psect = s->sectnum; + + if (sprite[ps[p].i].extra > 0) + { + if (x < 30000) + { + hittype[i].timetosleep++; + if (hittype[i].timetosleep >= (x >> 8)) + { + if (badguy(s)) + { + px = ps[p].oposx + 64 - (krand() & 127); + py = ps[p].oposy + 64 - (krand() & 127); + updatesector(px, py, &psect); + if (psect == -1) + { + i = nexti; + continue; + } + sx = s->x + 64 - (krand() & 127); + sy = s->y + 64 - (krand() & 127); + updatesector(px, py, &ssect); + if (ssect == -1) + { + i = nexti; + continue; + } + + if (!isRR() || s->pal == 33 || s->type == RR_VIXEN || + ((isRRRA()) && isIn(s->type, RR_COOT, RR_COOTSTAYPUT, RR_BIKERSTAND, RR_BIKERRIDE, + RR_BIKERRIDEDAISY, RR_MINIONAIRBOAT, RR_HULKAIRBOAT, + RR_DAISYAIRBOAT, RR_JACKOLOPE, RR_BANJOCOOTER, + RR_GUITARBILLY, RR_MAMAJACKOLOPE, RR_BIKERBV, + RR_MAKEOUT, RR_CHEER, RR_CHEERSTAYPUT)) || + (sintable[(s->ang + 512) & 2047] * (px - sx) + sintable[s->ang & 2047] * (py - sy) >= 0)) + { + int r1 = krand(); + int r2 = krand(); + j = cansee(sx, sy, s->z - (r2 % (52 << 8)), s->sectnum, px, py, ps[p].oposz - (r1 % (32 << 8)), ps[p].cursectnum); + } + } + else + { + int r1 = krand(); + int r2 = krand(); + j = cansee(s->x, s->y, s->z - ((r2 & 31) << 8), s->sectnum, ps[p].oposx, ps[p].oposy, ps[p].oposz - ((r1 & 31) << 8), ps[p].cursectnum); + } + + if (j) + { + bool res = (!isRR()) ? + isIn(s->picnum, + RUBBERCAN, + EXPLODINGBARREL, + WOODENHORSE, + HORSEONSIDE, + CANWITHSOMETHING, + CANWITHSOMETHING2, + CANWITHSOMETHING3, + CANWITHSOMETHING4, + FIREBARREL, + FIREVASE, + NUKEBARREL, + NUKEBARRELDENTED, + NUKEBARRELLEAKED, + TRIPBOMB) : + isIn(s->picnum, + RR_1251, + RR_1268, + RR_1187, + RR_1304, + RR_1305, + RR_1306, + RR_1309, + RR_1315, + RR_1317, + RR_1388); + + + if (res) + { + if (sector[s->sectnum].ceilingstat & 1) + s->shade = sector[s->sectnum].ceilingshade; + else s->shade = sector[s->sectnum].floorshade; + + hittype[i].timetosleep = 0; + changespritestat(i, STAT_STANDABLE); + } + else + { +#if 0 + // TRANSITIONAL: RedNukem has this here. Needed? + if (A_CheckSpriteFlags(spriteNum, SFLAG_USEACTIVATOR) && sector[sprite[spriteNum].sectnum].lotag & 16384) break; +#endif + hittype[i].timetosleep = 0; + check_fta_sounds(i); + changespritestat(i, STAT_ACTOR); + } + } + else hittype[i].timetosleep = 0; + } + } + if ((!isRR() || !j) && badguy(s)) + { + if (sector[s->sectnum].ceilingstat & 1) + s->shade = sector[s->sectnum].ceilingshade; + else s->shade = sector[s->sectnum].floorshade; + + if (isRR() && (s->picnum != RR_HEN || s->picnum != RR_COW || s->picnum != RR_PIG || s->picnum != RR_DOGRUN || ((isRRRA()) && s->picnum != RR_JACKOLOPE))) + if (wakeup(i, p)) + { + hittype[i].timetosleep = 0; + check_fta_sounds(i); + changespritestat(i, STAT_ACTOR); + } + + } + } + i = nexti; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +int ifhitsectors(int sectnum) +{ + int i = headspritestat[STAT_MISC]; + if (!isRR()) + { + while (i >= 0) + { + if (sprite[i].picnum == EXPLOSION2 && sectnum == sprite[i].sectnum) + return i; + i = nextspritestat[i]; + } + } + else + { + while (i >= 0) + { + if (sprite[i].picnum == RR_EXPLOSION2 || (sprite[i].picnum == RR_EXPLOSION3 && sectnum == sprite[i].sectnum)) + return i; + i = nextspritestat[i]; + } + } + + return -1; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +int ifhitbyweapon(int sn) +{ + short j, p; + spritetype* npc; + + if (hittype[sn].extra >= 0) + { + if (sprite[sn].extra >= 0) + { + npc = &sprite[sn]; + + if (npc->picnum == APLAYER) + { + if (ud.god && (isRR() || hittype[sn].picnum != SHRINKSPARK)) return -1; + + p = npc->yvel; + j = hittype[sn].owner; + + if (j >= 0 && + sprite[j].picnum == APLAYER && + ud.coop == 1 && + ud.ffire == 0) + return -1; + + npc->extra -= hittype[sn].extra; + + if (j >= 0) + { + if (npc->extra <= 0 && hittype[sn].picnum != pPick2(FREEZEBLAST, RR_ALIENBLAST)) + { + npc->extra = 0; + + ps[p].wackedbyactor = j; + + if (sprite[hittype[sn].owner].picnum == APLAYER && p != sprite[hittype[sn].owner].yvel) + { + // yvel contains player ID + ps[p].frag_ps = sprite[j].yvel; + } + + hittype[sn].owner = ps[p].i; + } + } + + bool res = !isRR() ? + isIn(hittype[sn].picnum, RADIUSEXPLOSION, RPG, HYDRENT, HEAVYHBOMB, SEENINE, OOZFILTER, EXPLODINGBARREL) : + (isIn(hittype[sn].picnum, RR_DYNAMITE, RR_POWDERKEGSPRITE, RR_1228, RR_1273, RR_1315, RR_SEENINE, RR_RADIUSEXPLOSION, RR_CROSSBOW) || + (isRRRA() && hittype[sn].picnum == RR_CHIKENCROSSBOW)); + + int shift = res ? 2 : 1; + ps[p].posxv += hittype[sn].extra * (sintable[(hittype[sn].ang + 512) & 2047]) << shift; + ps[p].posyv += hittype[sn].extra * (sintable[hittype[sn].ang & 2047]) << shift; + } + else + { + if (hittype[sn].extra == 0) + if ((isRR() || hittype[sn].picnum == SHRINKSPARK) && npc->xrepeat < 24) + return -1; + + if (isWorldTour() && hittype[sn].picnum == FIREFLY && npc->xrepeat < 48) + { + if (hittype[sn].picnum != RADIUSEXPLOSION && hittype[sn].picnum != RPG) + return -1; + } + + npc->extra -= hittype[sn].extra; + if (npc->picnum != pPick2(RECON, RR_4989) && npc->owner >= 0 && sprite[npc->owner].statnum < MAXSTATUS) + npc->owner = hittype[sn].owner; + } + + hittype[sn].extra = -1; + return hittype[sn].picnum; + } + } + + + if (ud.multimode < 2 || !isWorldTour() + || hittype[sn].picnum != FLAMETHROWERFLAME + || hittype[sn].extra >= 0 + || sprite[sn].extra > 0 + || sprite[sn].picnum != APLAYER + || ps[sprite[sn].yvel].numloogs > 0 + || hittype[sn].owner < 0) + { + hittype[sn].extra = -1; + return -1; + } + else + { + p = sprite[sn].yvel; + sprite[sn].extra = 0; + ps[p].wackedbyactor = (short)hittype[sn].owner; + + if (sprite[hittype[sn].owner].picnum == APLAYER && p != hittype[sn].owner) + ps[p].frag_ps = (short)hittype[sn].owner; + + hittype[sn].owner = ps[p].i; + hittype[sn].extra = -1; + + return FLAMETHROWERFLAME; + } + + + hittype[sn].extra = -1; + return -1; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movecyclers(void) +{ + short q, j, x, t, s, * c; + walltype* wal; + char cshade; + + for (q = numcyclers - 1; q >= 0; q--) + { + + c = &cyclers[q][0]; + s = c[0]; + + t = c[3]; + j = t + (sintable[c[1] & 2047] >> 10); + cshade = c[2]; + + if (j < cshade) j = cshade; + else if (j > t) j = t; + + c[1] += sector[s].extra; + if (c[5]) + { + wal = &wall[sector[s].wallptr]; + for (x = sector[s].wallnum; x > 0; x--, wal++) + if (wal->hitag != 1) + { + wal->shade = j; + + if ((wal->cstat & 2) && wal->nextwall >= 0) + wall[wal->nextwall].shade = j; + + } + sector[s].floorshade = sector[s].ceilingshade = j; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movedummyplayers(void) +{ + short i, p, nexti; + + i = headspritestat[STAT_DUMMYPLAYER]; + while (i >= 0) + { + nexti = nextspritestat[i]; + + p = sprite[sprite[i].owner].yvel; + + if ((!isRR() && ps[p].on_crane >= 0) || sector[ps[p].cursectnum].lotag != 1 || sprite[ps[p].i].extra <= 0) + { + ps[p].dummyplayersprite = -1; + deletesprite(i); + i = nexti; + continue; + } + else + { + if (ps[p].on_ground && ps[p].on_warping_sector == 1 && sector[ps[p].cursectnum].lotag == 1) + { + sprite[i].cstat = 257; + sprite[i].z = sector[sprite[i].sectnum].ceilingz + (27 << 8); + sprite[i].ang = ps[p].q16ang >> FRACBITS; + if (hittype[i].temp_data[0] == 8) + hittype[i].temp_data[0] = 0; + else hittype[i].temp_data[0]++; + } + else + { + if (sector[sprite[i].sectnum].lotag != 2) sprite[i].z = sector[sprite[i].sectnum].floorz; + sprite[i].cstat = (short)32768; + } + } + + sprite[i].x += (ps[p].posx - ps[p].oposx); + sprite[i].y += (ps[p].posy - ps[p].oposy); + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + i = nexti; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +int otherp; +void moveplayers(void) //Players +{ + short i, nexti; + int otherx; + spritetype* s; + struct player_struct* p; + + i = headspritestat[STAT_PLAYER]; + while (i >= 0) + { + nexti = nextspritestat[i]; + + s = &sprite[i]; + p = &ps[s->yvel]; + if (s->owner >= 0) + { + if (p->newowner >= 0) //Looking thru the camera + { + s->x = p->oposx; + s->y = p->oposy; + hittype[i].bposz = s->z = p->oposz + PHEIGHT; + s->ang = p->oq16ang >> FRACBITS; + setsprite(i, s->x, s->y, s->z); + } + else + { + if (ud.multimode > 1) + otherp = findotherplayer(s->yvel, &otherx); + else + { + otherp = s->yvel; + otherx = 0; + } + + execute(i, s->yvel, otherx); + + p->oq16ang = p->q16ang; + + if (ud.multimode > 1) + if (sprite[ps[otherp].i].extra > 0) + { + if (s->yrepeat > 32 && sprite[ps[otherp].i].yrepeat < 32) + { + if (otherx < 1400 && p->knee_incs == 0) + { + p->knee_incs = 1; + p->weapon_pos = -1; + p->actorsqu = ps[otherp].i; + } + } + } + if (ud.god) + { + s->extra = p->max_player_health; + s->cstat = 257; + if (!isWW2GI() && !isRR()) + p->jetpack_amount = 1599; + } + + + if (s->extra > 0) + { + // currently alive... + + hittype[i].owner = i; + + if (ud.god == 0) + if (ceilingspace(s->sectnum) || floorspace(s->sectnum)) + quickkill(p); + } + else + { + + p->posx = s->x; + p->posy = s->y; + p->posz = s->z - (20 << 8); + + p->newowner = -1; + + if (p->wackedbyactor >= 0 && sprite[p->wackedbyactor].statnum < MAXSTATUS) + { + int ang = p->q16ang >> FRACBITS; + ang += getincangle(ang, getangle(sprite[p->wackedbyactor].x - p->posx, sprite[p->wackedbyactor].y - p->posy)) >> 1; + ang &= 2047; + p->q16ang = ang << FRACBITS; + } + + } + s->ang = p->q16ang >> FRACBITS; + } + } + else + { + if (p->holoduke_on == -1) + { + deletesprite(i); + i = nexti; + continue; + } + + hittype[i].bposx = s->x; + hittype[i].bposy = s->y; + hittype[i].bposz = s->z; + + s->cstat = 0; + + if (s->xrepeat < 42) + { + s->xrepeat += 4; + s->cstat |= 2; + } + else s->xrepeat = 42; + if (s->yrepeat < 36) + s->yrepeat += 4; + else + { + s->yrepeat = 36; + if (sector[s->sectnum].lotag != ST_2_UNDERWATER) + makeitfall(i); + if (s->zvel == 0 && sector[s->sectnum].lotag == ST_1_ABOVE_WATER) + s->z += (32 << 8); + } + + if (s->extra < 8) + { + s->xvel = 128; + s->ang = p->q16ang >> FRACBITS; + s->extra++; + //IFMOVING; // JBF 20040825: is really "if (ssp(i,CLIPMASK0)) ;" which is probably + ssp(i, CLIPMASK0); // not the safest of ideas because a zealous optimiser probably sees + // it as redundant, so I'll call the "ssp(i,CLIPMASK0)" explicitly. + } + else + { + s->ang = 2047 - (p->q16ang >> FRACBITS); + setsprite(i, s->x, s->y, s->z); + } + } + + if (sector[s->sectnum].ceilingstat & 1) + s->shade += (sector[s->sectnum].ceilingshade - s->shade) >> 1; + else + s->shade += (sector[s->sectnum].floorshade - s->shade) >> 1; + + i = nexti; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movefx(void) +{ + short i, j, nexti, p; + int x, ht; + spritetype* s; + + i = headspritestat[STAT_FX]; + while (i >= 0) + { + s = &sprite[i]; + + nexti = nextspritestat[i]; + + switch (s->picnum) + { + case RESPAWN: + if (sprite[i].extra == 66) + { + j = spawn(i, sprite[i].hitag); + if (isRRRA()) + { + sprite[j].pal = sprite[i].pal; + if (sprite[j].picnum == RR_MAMAJACKOLOPE) + { + if (sprite[j].pal == 30) + { + sprite[j].xrepeat = 26; + sprite[j].yrepeat = 26; + sprite[j].clipdist = 75; + } + else if (sprite[j].pal == 31) + { + sprite[j].xrepeat = 36; + sprite[j].yrepeat = 36; + sprite[j].clipdist = 100; + } + else if (sprite[j].pal == 32) + { + sprite[j].xrepeat = 50; + sprite[j].yrepeat = 50; + sprite[j].clipdist = 100; + } + else + { + sprite[j].xrepeat = 50; + sprite[j].yrepeat = 50; + sprite[j].clipdist = 100; + } + } + + if (sprite[j].pal == 8) + { + sprite[j].cstat |= 2; + } + + if (sprite[j].pal != 6) + { + deletesprite(i); + i = nexti; + continue; + } + sprite[i].extra = (66 - 13); + sprite[j].pal = 0; + } + else + { + deletesprite(i); + i = nexti; + continue; + } + } + else if (sprite[i].extra > (66 - 13)) + sprite[i].extra++; + break; + + case MUSICANDSFX: + + ht = s->hitag; + + if (hittype[i].temp_data[1] != (int)SoundEnabled()) + { + hittype[i].temp_data[1] = SoundEnabled(); + hittype[i].temp_data[0] = 0; + } + + if (s->lotag >= 1000 && s->lotag < 2000) + { + x = ldist(&sprite[ps[screenpeek].i], s); + if (x < ht && hittype[i].temp_data[0] == 0) + { + FX_SetReverb(s->lotag - 1000); + hittype[i].temp_data[0] = 1; + } + if (x >= ht && hittype[i].temp_data[0] == 1) + { + FX_SetReverb(0); + FX_SetReverbDelay(0); + hittype[i].temp_data[0] = 0; + } + } + else if (s->lotag < 999 && (unsigned)sector[s->sectnum].lotag < ST_9_SLIDING_ST_DOOR && snd_ambience && sector[sprite[i].sectnum].floorz != sector[sprite[i].sectnum].ceilingz) + { + auto flags = S_GetUserFlags(s->lotag); + if (flags & SF_MSFX) + { + int x = dist(&sprite[ps[screenpeek].i], s); + + if (x < ht && hittype[i].temp_data[0] == 0) + { + // Start playing an ambience sound. + A_PlaySound(s->lotag, i, CHAN_AUTO, CHANF_LOOP); + hittype[i].temp_data[0] = 1; // AMBIENT_SFX_PLAYING + } + else if (x >= ht && hittype[i].temp_data[0] == 1) + { + // Stop playing ambience sound because we're out of its range. + S_StopEnvSound(s->lotag, i); + } + } + + if ((flags & (SF_GLOBAL | SF_DTAG)) == SF_GLOBAL) + { + if (hittype[i].temp_data[4] > 0) hittype[i].temp_data[4]--; + else for (p = connecthead; p >= 0; p = connectpoint2[p]) + if (p == myconnectindex && ps[p].cursectnum == s->sectnum) + { + S_PlaySound(s->lotag + (unsigned)global_random % (s->hitag + 1)); + hittype[i].temp_data[4] = 26 * 40 + (global_random % (26 * 40)); + } + } + } + break; + } + i = nexti; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movefallers(void) +{ + short i, nexti, sect, j; + spritetype* s; + int x; + + i = headspritestat[STAT_FALLER]; + while (i >= 0) + { + nexti = nextspritestat[i]; + s = &sprite[i]; + + sect = s->sectnum; + + if (hittype[i].temp_data[0] == 0) + { + s->z -= (16 << 8); + hittype[i].temp_data[1] = s->ang; + x = s->extra; + j = ifhitbyweapon(i); + if (j >= 0) + { + bool res = !isRR() ? + isIn(j, FIREEXT, RPG, RADIUSEXPLOSION, SEENINE, OOZFILTER) : + (isIn(j, RR_CROSSBOW, RR_RADIUSEXPLOSION, RR_SEENINE, RR_OOZFILTER) || (isRRRA() && j == RR_CHIKENCROSSBOW)); + + if (res) + { + if (s->extra <= 0) + { + hittype[i].temp_data[0] = 1; + j = headspritestat[12]; + while (j >= 0) + { + if (sprite[j].hitag == sprite[i].hitag) + { + hittype[j].temp_data[0] = 1; + sprite[j].cstat &= (65535 - 64); + if (!isRR() ? isIn(j, CEILINGSTEAM, STEAM) : isIn(j, RR_CEILINGSTEAM, RR_STEAM)) + sprite[j].cstat |= 32768; + } + j = nextspritestat[j]; + } + } + } + else + { + hittype[i].extra = 0; + s->extra = x; + } + } + s->ang = hittype[i].temp_data[1]; + s->z += (16 << 8); + } + else if (hittype[i].temp_data[0] == 1) + { + if (s->lotag > 0) + { + s->lotag -= 3; + if (isRR()) + { + s->xvel = (64 + krand()) & 127; + s->zvel = -(1024 + (krand() & 1023)); + } + else if (s->lotag <= 0) + { + s->xvel = (32 + (krand() & 63)); + s->zvel = -(1024 + (krand() & 1023)); + } + } + else + { + if (s->xvel > 0) + { + s->xvel -= isRR()? 2 : 8; + ssp(i, CLIPMASK0); + } + + if (floorspace(s->sectnum)) x = 0; + else + { + if (ceilingspace(s->sectnum)) + x = gc / 6; + else + x = gc; + } + + if (s->z < (sector[sect].floorz - FOURSLEIGHT)) + { + s->zvel += x; + if (s->zvel > 6144) + s->zvel = 6144; + s->z += s->zvel; + } + if ((sector[sect].floorz - s->z) < (16 << 8)) + { + j = 1 + (krand() & 7); + for (x = 0; x < j; x++) RANDOMSCRAP(s, i); + deletesprite(i); + } + } + } + + i = nexti; + } +} + +//--------------------------------------------------------------------------- +// +// split out of movestandables +// +//--------------------------------------------------------------------------- + +static void movecrane(int i) +{ + auto t = &hittype[i].temp_data[0]; + auto s = &sprite[i]; + int sect = s->sectnum; + int x; + int crane = pPick(CRANE); + + //t[0] = state + //t[1] = checking sector number + + if (s->xvel) getglobalz(i); + + if (t[0] == 0) //Waiting to check the sector + { + int j = headspritesect[t[1]]; + while (j >= 0) + { + int nextj = nextspritesect[j]; + switch (sprite[j].statnum) + { + case STAT_ACTOR: + case STAT_ZOMBIEACTOR: + case STAT_STANDABLE: + case STAT_PLAYER: + s->ang = getangle(msx[t[4] + 1] - s->x, msy[t[4] + 1] - s->y); + setsprite(j, msx[t[4] + 1], msy[t[4] + 1], sprite[j].z); + t[0]++; + deletesprite(i); + return; + } + j = nextj; + } + } + + else if (t[0] == 1) + { + if (s->xvel < 184) + { + s->picnum = crane + 1; + s->xvel += 8; + } + //IFMOVING; // JBF 20040825: see my rant above about this + ssp(i, CLIPMASK0); + if (sect == t[1]) + t[0]++; + } + else if (t[0] == 2 || t[0] == 7) + { + s->z += (1024 + 512); + + if (t[0] == 2) + { + if ((sector[sect].floorz - s->z) < (64 << 8)) + if (s->picnum > crane) s->picnum--; + + if ((sector[sect].floorz - s->z) < (4096 + 1024)) + t[0]++; + } + if (t[0] == 7) + { + if ((sector[sect].floorz - s->z) < (64 << 8)) + { + if (s->picnum > crane) s->picnum--; + else + { + if (s->owner == -2) + { + auto p = findplayer(s, &x); + spritesound(isRR() ? 390 : DUKE_GRUNT, ps[p].i); + if (ps[p].on_crane == i) + ps[p].on_crane = -1; + } + t[0]++; + s->owner = -1; + } + } + } + } + else if (t[0] == 3) + { + s->picnum++; + if (s->picnum == (crane + 2)) + { + auto p = checkcursectnums(t[1]); + if (p >= 0 && ps[p].on_ground) + { + s->owner = -2; + ps[p].on_crane = i; + spritesound(isRR() ? 390 : DUKE_GRUNT, ps[p].i); + ps[p].q16ang = (s->ang + 1024) << FRACBITS; + } + else + { + int j = headspritesect[t[1]]; + while (j >= 0) + { + switch (sprite[j].statnum) + { + case 1: + case 6: + s->owner = j; + break; + } + j = nextspritesect[j]; + } + } + + t[0]++;//Grabbed the sprite + t[2] = 0; + return; + } + } + else if (t[0] == 4) //Delay before going up + { + t[2]++; + if (t[2] > 10) + t[0]++; + } + else if (t[0] == 5 || t[0] == 8) + { + if (t[0] == 8 && s->picnum < (crane + 2)) + if ((sector[sect].floorz - s->z) > 8192) + s->picnum++; + + if (s->z < msx[t[4] + 2]) + { + t[0]++; + s->xvel = 0; + } + else + s->z -= (1024 + 512); + } + else if (t[0] == 6) + { + if (s->xvel < 192) + s->xvel += 8; + s->ang = getangle(msx[t[4]] - s->x, msy[t[4]] - s->y); + //IFMOVING; // JBF 20040825: see my rant above about this + ssp(i, CLIPMASK0); + if (((s->x - msx[t[4]]) * (s->x - msx[t[4]]) + (s->y - msy[t[4]]) * (s->y - msy[t[4]])) < (128 * 128)) + t[0]++; + } + + else if (t[0] == 9) + t[0] = 0; + + setsprite(msy[t[4] + 2], s->x, s->y, s->z - (34 << 8)); + + if (s->owner != -1) + { + auto p = findplayer(s, &x); + + int j = ifhitbyweapon(i); + if (j >= 0) + { + if (s->owner == -2) + if (ps[p].on_crane == i) + ps[p].on_crane = -1; + s->owner = -1; + s->picnum = crane; + return; + } + + if (s->owner >= 0) + { + setsprite(s->owner, s->x, s->y, s->z); + + hittype[s->owner].bposx = s->x; + hittype[s->owner].bposy = s->y; + hittype[s->owner].bposz = s->z; + + s->zvel = 0; + } + else if (s->owner == -2) + { + auto ang = ps[p].q16ang >> FRACBITS; + ps[p].oposx = ps[p].posx = s->x - (sintable[(ang + 512) & 2047] >> 6); + ps[p].oposy = ps[p].posy = s->y - (sintable[ang & 2047] >> 6); + ps[p].oposz = ps[p].posz = s->z + (2 << 8); + setsprite(ps[p].i, ps[p].posx, ps[p].posy, ps[p].posz); + ps[p].cursectnum = sprite[ps[p].i].sectnum; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movefountain(int i) +{ + auto t = &hittype[i].temp_data[0]; + auto s = &sprite[i]; + int x; + if (t[0] > 0) + { + if (t[0] < 20) + { + t[0]++; + + s->picnum++; + + if (s->picnum == (pPick(WATERFOUNTAIN) + 3)) + s->picnum = pPick(WATERFOUNTAIN) + 1; + } + else + { + findplayer(s, &x); + + if (x > 512) + { + t[0] = 0; + s->picnum = pPick(WATERFOUNTAIN); + } + else t[0] = 1; + } + } +} +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void moveflammable(int i) +{ + auto s = &sprite[i]; + int j; + if (hittype[i].temp_data[0] == 1) + { + hittype[i].temp_data[1]++; + if ((hittype[i].temp_data[1] & 3) > 0) return; + + if (!isRR() && s->picnum == TIRE && hittype[i].temp_data[1] == 32) + { + s->cstat = 0; + j = spawn(i, BLOODPOOL); + sprite[j].shade = 127; + } + else + { + if (s->shade < 64) s->shade++; + else + { + deletesprite(i); + return; + } + } + + j = s->xrepeat - (krand() & 7); + if (j < 10) + { + deletesprite(i); + return; + } + + s->xrepeat = j; + + j = s->yrepeat - (krand() & 7); + if (j < 4) + { + deletesprite(i); + return; + } + s->yrepeat = j; + } + if (!isRR() && s->picnum == BOX) + { + makeitfall(i); + hittype[i].ceilingz = sector[s->sectnum].ceilingz; + } +} + +//--------------------------------------------------------------------------- +// +// Duke only +// +//--------------------------------------------------------------------------- + +static void movetripbomb(int i) +{ + auto s = &sprite[i]; + int j, x; + int lTripBombControl = GetGameVar("TRIPBOMB_CONTROL", TRIPBOMB_TRIPWIRE, -1, -1); + if (lTripBombControl & TRIPBOMB_TIMER) + { + // we're on a timer.... + if (s->extra >= 0) + { + s->extra--; + if (s->extra == 0) + { + hittype[i].temp_data[2] = 16; + spritesound(LASERTRIP_ARMING, i); + } + } + } + if (hittype[i].temp_data[2] > 0) + { + hittype[i].temp_data[2]--; + if (hittype[i].temp_data[2] == 8) + { + spritesound(LASERTRIP_EXPLODE, i); + for (j = 0; j < 5; j++) RANDOMSCRAP(s, i); + x = s->extra; + hitradius(i, tripbombblastradius, x >> 2, x >> 1, x - (x >> 2), x); + + j = spawn(i, EXPLOSION2); + sprite[j].ang = s->ang; + sprite[j].xvel = 348; + ssp(j, CLIPMASK0); + + j = headspritestat[5]; + while (j >= 0) + { + if (sprite[j].picnum == LASERLINE && s->hitag == sprite[j].hitag) + sprite[j].xrepeat = sprite[j].yrepeat = 0; + j = nextspritestat[j]; + } + deletesprite(i); + } + return; + } + else + { + x = s->extra; + s->extra = 1; + int16_t l = s->ang; + j = ifhitbyweapon(i); + if (j >= 0) + { + hittype[i].temp_data[2] = 16; + } + s->extra = x; + s->ang = l; + } + + if (hittype[i].temp_data[0] < 32) + { + findplayer(s, &x); + if (x > 768) hittype[i].temp_data[0]++; + else if (hittype[i].temp_data[0] > 16) hittype[i].temp_data[0]++; + } + if (hittype[i].temp_data[0] == 32) + { + int16_t l = s->ang; + s->ang = hittype[i].temp_data[5]; + + hittype[i].temp_data[3] = s->x; hittype[i].temp_data[4] = s->y; + s->x += sintable[(hittype[i].temp_data[5] + 512) & 2047] >> 9; + s->y += sintable[(hittype[i].temp_data[5]) & 2047] >> 9; + s->z -= (3 << 8); + setsprite(i, s->x, s->y, s->z); + + int16_t m; + x = hitasprite(i, &m); + + hittype[i].lastvx = x; + + s->ang = l; + + int k = 0; + + if (lTripBombControl & TRIPBOMB_TRIPWIRE) + { + // we're on a trip wire + while (x > 0) + { + j = spawn(i, LASERLINE); + setsprite(j, sprite[j].x, sprite[j].y, sprite[j].z); + sprite[j].hitag = s->hitag; + hittype[j].temp_data[1] = sprite[j].z; + + s->x += sintable[(hittype[i].temp_data[5] + 512) & 2047] >> 4; + s->y += sintable[(hittype[i].temp_data[5]) & 2047] >> 4; + + if (x < 1024) + { + sprite[j].xrepeat = x >> 5; + break; + } + x -= 1024; + } + } + + hittype[i].temp_data[0]++; + s->x = hittype[i].temp_data[3]; s->y = hittype[i].temp_data[4]; + s->z += (3 << 8); + setsprite(i, s->x, s->y, s->z); + hittype[i].temp_data[3] = 0; + if (m >= 0 && lTripBombControl & TRIPBOMB_TRIPWIRE) + { + hittype[i].temp_data[2] = 13; + spritesound(LASERTRIP_ARMING, i); + } + else hittype[i].temp_data[2] = 0; + } + if (hittype[i].temp_data[0] == 33) + { + hittype[i].temp_data[1]++; + + + hittype[i].temp_data[3] = s->x; hittype[i].temp_data[4] = s->y; + s->x += sintable[(hittype[i].temp_data[5] + 512) & 2047] >> 9; + s->y += sintable[(hittype[i].temp_data[5]) & 2047] >> 9; + s->z -= (3 << 8); + setsprite(i, s->x, s->y, s->z); + + int16_t m; + x = hitasprite(i, &m); + + s->x = hittype[i].temp_data[3]; s->y = hittype[i].temp_data[4]; + s->z += (3 << 8); + setsprite(i, s->x, s->y, s->z); + + if (hittype[i].lastvx != x && lTripBombControl & TRIPBOMB_TRIPWIRE) + { + hittype[i].temp_data[2] = 13; + spritesound(LASERTRIP_ARMING, i); + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void detonate(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + earthquaketime = 16; + + int j = headspritestat[STAT_EFFECTOR]; + while (j >= 0) + { + if (s->hitag == sprite[j].hitag) + { + if (sprite[j].lotag == SE_13_EXPLOSIVE) + { + if (hittype[j].temp_data[2] == 0) + hittype[j].temp_data[2] = 1; + } + else if (sprite[j].lotag == SE_8_UP_OPEN_DOOR_LIGHTS) + hittype[j].temp_data[4] = 1; + else if (sprite[j].lotag == SE_18_INCREMENTAL_SECTOR_RISE_FALL) + { + if (hittype[j].temp_data[0] == 0) + hittype[j].temp_data[0] = 1; + } + else if (sprite[j].lotag == SE_21_DROP_FLOOR) + hittype[j].temp_data[0] = 1; + } + j = nextspritestat[j]; + } + + s->z -= (32 << 8); + + if ((t[3] == 1 && s->xrepeat) || s->lotag == -99) + { + int x = s->extra; + spawn(i, EXPLOSION2); + hitradius(i, seenineblastradius, x >> 2, x - (x >> 1), x - (x >> 2), x); + spritesound(PIPEBOMB_EXPLODE, i); + } + + if (s->xrepeat) + for (int x = 0; x < 8; x++) RANDOMSCRAP(s, i); + + deletesprite(i); + +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movecrack(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + if (s->hitag > 0) + { + t[0] = s->cstat; + t[1] = s->ang; + int j = ifhitbyweapon(i); + + bool res = !isRR() ? + isIn(j, FIREEXT, RPG, RADIUSEXPLOSION, SEENINE, OOZFILTER) : + (isIn(j, RR_CROSSBOW, RR_RADIUSEXPLOSION, RR_SEENINE, RR_OOZFILTER) || (isRRRA() && j == RR_CHIKENCROSSBOW)); + + if (res) + { + j = headspritestat[STAT_STANDABLE]; + while (j >= 0) + { + if (s->hitag == sprite[j].hitag && (isRR() ? isIn(sprite[j].picnum, RR_OOZFILTER, RR_SEENINE) : isIn(sprite[j].picnum, OOZFILTER, SEENINE))) + if (sprite[j].shade != -32) + sprite[j].shade = -32; + j = nextspritestat[j]; + } + detonate(i); + } + else + { + s->cstat = t[0]; + s->ang = t[1]; + s->extra = 0; + } + } +} + +//--------------------------------------------------------------------------- +// +// Duke only +// +//--------------------------------------------------------------------------- + +static void movefireext(int i) +{ + int j = ifhitbyweapon(i); + if (j == -1) return; + + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + + for (int k = 0; k < 16; k++) + { + j = EGS(sprite[i].sectnum, sprite[i].x, sprite[i].y, sprite[i].z - (krand() % (48 << 8)), SCRAP3 + (krand() & 3), -8, 48, 48, krand() & 2047, (krand() & 63) + 64, -(krand() & 4095) - (sprite[i].zvel >> 2), i, 5); + sprite[j].pal = 2; + } + + spawn(i, EXPLOSION2); + spritesound(PIPEBOMB_EXPLODE, i); + spritesound(GLASS_HEAVYBREAK, i); + + if (s->hitag > 0) + { + j = headspritestat[6]; + while (j >= 0) + { + if (s->hitag == sprite[j].hitag && (sprite[j].picnum == OOZFILTER || sprite[j].picnum == SEENINE)) + if (sprite[j].shade != -32) + sprite[j].shade = -32; + j = nextspritestat[j]; + } + + int x = s->extra; + spawn(i, EXPLOSION2); + hitradius(i, pipebombblastradius, x >> 2, x - (x >> 1), x - (x >> 2), x); + spritesound(PIPEBOMB_EXPLODE, i); + detonate(i); + } + else + { + hitradius(i, seenineblastradius, 10, 15, 20, 25); + deletesprite(i); + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void moveooz(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + int j; + if (s->shade != -32 && s->shade != -33) + { + if (s->xrepeat) + j = (ifhitbyweapon(i) >= 0); + else + j = 0; + + if (j || s->shade == -31) + { + if (j) s->lotag = 0; + + t[3] = 1; + + j = headspritestat[STAT_STANDABLE]; + while (j >= 0) + { + if (s->hitag == sprite[j].hitag && (sprite[j].picnum == pPick(SEENINE) || sprite[j].picnum == pPick(OOZFILTER))) + sprite[j].shade = -32; + j = nextspritestat[j]; + } + } + } + else + { + if (s->shade == -32) + { + if (s->lotag > 0) + { + s->lotag -= 3; + if (s->lotag <= 0) s->lotag = -99; + } + else + s->shade = -33; + } + else + { + if (s->xrepeat > 0) + { + hittype[i].temp_data[2]++; + if (hittype[i].temp_data[2] == 3) + { + if (s->picnum == pPick(OOZFILTER)) + { + hittype[i].temp_data[2] = 0; + detonate(i); + return; + } + if (s->picnum != (pPick(SEENINEDEAD) + 1)) + { + hittype[i].temp_data[2] = 0; + + if (s->picnum == pPick(SEENINEDEAD)) s->picnum++; + else if (s->picnum == pPick(SEENINE)) + s->picnum = pPick(SEENINEDEAD); + } + else + { + detonate(i); + return; + } + } + return; + } + detonate(i); + return; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movemasterswitch(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + if (s->yvel == 1) + { + s->hitag--; + if (s->hitag <= 0) + { + operatesectors(s->sectnum, i); + + int j = headspritesect[s->sectnum]; + while (j >= 0) + { + if (sprite[j].statnum == 3) + { + switch (sprite[j].lotag) + { + case SE_2_EARTHQUAKE: + case SE_21_DROP_FLOOR: + case SE_31_FLOOR_RISE_FALL: + case SE_32_CEILING_RISE_FALL: + case SE_36_PROJ_SHOOTER: + hittype[j].temp_data[0] = 1; + break; + case SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT: + hittype[j].temp_data[4] = 1; + break; + } + } + else if (sprite[j].statnum == 6) + { + if (sprite[j].picnum == pPick(SEENINE) || sprite[j].picnum == pPick(OOZFILTER)) + { + sprite[j].shade = -31; + } + } + j = nextspritesect[j]; + } + deletesprite(i); + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void moveviewscreen(int i) +{ + auto s = &sprite[i]; + if (s->xrepeat == 0) deletesprite(i); + else + { + int x; + findplayer(s, &x); + + if (x < 2048) + { +#if 0 + if (SP == 1) + camsprite = i; +#endif + } + else if (camsprite != -1 && hittype[i].temp_data[0] == 1) + { + camsprite = -1; + s->yvel = 0; + hittype[i].temp_data[0] = 0; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movetrash(int i) +{ + auto s = &sprite[i]; + if (s->xvel == 0) s->xvel = 1; + if (ssp(i, CLIPMASK0)) + { + makeitfall(i); + if (krand() & 1) s->zvel -= 256; + if (klabs(s->xvel) < 48) + s->xvel += (krand() & 3); + } + else deletesprite(i); +} + +//--------------------------------------------------------------------------- +// +// Duke only +// +//--------------------------------------------------------------------------- + +static void movesidebolt(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + int x; + int sect = s->sectnum; + + auto p = findplayer(s, &x); + if (x > 20480) return; + +CLEAR_THE_BOLT2: + if (t[2]) + { + t[2]--; + return; + } + if ((s->xrepeat | s->yrepeat) == 0) + { + s->xrepeat = t[0]; + s->yrepeat = t[1]; + } + if ((krand() & 8) == 0) + { + t[0] = s->xrepeat; + t[1] = s->yrepeat; + t[2] = global_random & 4; + s->xrepeat = s->yrepeat = 0; + goto CLEAR_THE_BOLT2; + } + s->picnum++; + +#if 0 + // content of l was undefined. + if (l & 1) s->cstat ^= 2; +#endif + + if ((krand() & 1) && sector[sect].floorpicnum == HURTRAIL) + spritesound(SHORT_CIRCUIT, i); + + if (s->picnum == SIDEBOLT1 + 4) s->picnum = SIDEBOLT1; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movebolt(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + int x; + int sect = s->sectnum; + + auto p = findplayer(s, &x); + if (x > 20480) return; + + if (t[3] == 0) + t[3] = sector[sect].floorshade; + +CLEAR_THE_BOLT: + if (t[2]) + { + t[2]--; + sector[sect].floorshade = 20; + sector[sect].ceilingshade = 20; + return; + } + if ((s->xrepeat | s->yrepeat) == 0) + { + s->xrepeat = t[0]; + s->yrepeat = t[1]; + } + else if ((krand() & 8) == 0) + { + t[0] = s->xrepeat; + t[1] = s->yrepeat; + t[2] = global_random & 4; + s->xrepeat = s->yrepeat = 0; + goto CLEAR_THE_BOLT; + } + s->picnum++; + + int l = global_random & 7; + s->xrepeat = l + 8; + + if (l & 1) s->cstat ^= 2; + + auto bolt1 = pPick(BOLT1); + if (s->picnum == (bolt1 + 1) && (isRR() ? (krand() & 1) != 0 : (krand() & 7) == 0) && sector[sect].floorpicnum == pPick(HURTRAIL) ) + spritesound(SHORT_CIRCUIT, i); + + if (s->picnum == bolt1 + 4) s->picnum = bolt1; + + if (s->picnum & 1) + { + sector[sect].floorshade = 0; + sector[sect].ceilingshade = 0; + } + else + { + sector[sect].floorshade = 20; + sector[sect].ceilingshade = 20; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movewaterdrip(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + int sect = s->sectnum; + + if (t[1]) + { + t[1]--; + if (t[1] == 0) + s->cstat &= 32767; + } + else + { + makeitfall(i); + ssp(i, CLIPMASK0); + if (s->xvel > 0) s->xvel -= 2; + + if (s->zvel == 0) + { + s->cstat |= 32768; + + if (s->pal != 2 && (isRR() || s->hitag == 0)) + spritesound(SOMETHING_DRIPPING, i); + + if (sprite[s->owner].picnum != pPick(WATERDRIP)) + { + deletesprite(i); + } + else + { + hittype[i].bposz = s->z = t[0]; + t[1] = 48 + (krand() & 31); + } + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movedoorshock(int i) +{ + auto s = &sprite[i]; + int sect = s->sectnum; + int j = abs(sector[sect].ceilingz - sector[sect].floorz) >> 9; + s->yrepeat = j + 4; + s->xrepeat = 16; + s->z = sector[sect].floorz; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movetouchplate(int i) +{ + auto s = &sprite[i]; + auto t = &hittype[i].temp_data[0]; + int sect = s->sectnum; + int x; + int p; + + if (t[1] == 1 && s->hitag >= 0) //Move the sector floor + { + x = sector[sect].floorz; + + if (t[3] == 1) + { + if (x >= t[2]) + { + sector[sect].floorz = x; + t[1] = 0; + } + else + { + sector[sect].floorz += sector[sect].extra; + p = checkcursectnums(sect); + if (p >= 0) ps[p].posz += sector[sect].extra; + } + } + else + { + if (x <= s->z) + { + sector[sect].floorz = s->z; + t[1] = 0; + } + else + { + sector[sect].floorz -= sector[sect].extra; + p = checkcursectnums(sect); + if (p >= 0) + ps[p].posz -= sector[sect].extra; + } + } + return; + } + + if (t[5] == 1) return; + + p = checkcursectnums(sect); + if (p >= 0 && (ps[p].on_ground || s->ang == 512)) + { + if (t[0] == 0 && !check_activator_motion(s->lotag)) + { + t[0] = 1; + t[1] = 1; + t[3] = !t[3]; + operatemasterswitches(s->lotag); + operateactivators(s->lotag, p); + if (s->hitag > 0) + { + s->hitag--; + if (s->hitag == 0) t[5] = 1; + } + } + } + else t[0] = 0; + + if (t[1] == 1) + { + int j = headspritestat[STAT_STANDABLE]; + while (j >= 0) + { + if (j != i && sprite[j].picnum == TOUCHPLATE && sprite[j].lotag == s->lotag) + { + hittype[j].temp_data[1] = 1; + hittype[j].temp_data[3] = t[3]; + } + j = nextspritestat[j]; + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movecanwithsomething(int i) +{ + auto s = &sprite[i]; + makeitfall(i); + int j = ifhitbyweapon(i); + if (j >= 0) + { + spritesound(VENT_BUST, i); + for (j = 0; j < 10; j++) + RANDOMSCRAP(s, i); + + if (s->lotag) spawn(i, s->lotag); + + deletesprite(i); + } +} + +//--------------------------------------------------------------------------- +// +// this has been broken up into lots of smaller subfunctions +// +//--------------------------------------------------------------------------- + +void movestandables(void) +{ + int nexti; + + for (int i = headspritestat[STAT_STANDABLE]; i >= 0; i = nexti) + { + nexti = nextspritestat[i]; + + auto s = &sprite[i]; + int picnum = s->picnum; + + if (s->sectnum < 0) + { + deletesprite(i); + continue; + } + + hittype[i].bposx = s->x; + hittype[i].bposy = s->y; + hittype[i].bposz = s->z; + + + if (picnum >= pPick(CRANE) && picnum <= pPick(CRANE) +3) + { + movecrane(i); + } + + else if (picnum >= pPick(WATERFOUNTAIN) && picnum <= pPick(WATERFOUNTAIN) + 3) + { + movefountain(i); + } + + else if (AFLAMABLE(picnum)) + { + moveflammable(i); + } + + else if (!isRR() && picnum == TRIPBOMB) + { + movetripbomb(i); + } + + else if (picnum >= pPick(CRACK1) && picnum <= pPick(CRACK1)+3) + { + movecrack(i); + } + + else if (!isRR() && picnum == FIREEXT) + { + movefireext(i); + } + + else if (picnum == pPick(OOZFILTER) || picnum == pPick(SEENINE) || picnum == pPick(SEENINEDEAD) || picnum == (pPick(SEENINEDEAD) + 1)) + { + moveooz(i); + } + + else if (picnum == MASTERSWITCH) + { + movemasterswitch(i); + } + + else if (!isRR() && (picnum == VIEWSCREEN || picnum == VIEWSCREEN2)) + { + moveviewscreen(i); + } + + else if (picnum == pPick(TRASH)) + { + movetrash(i); + } + + else if (!isRR() && picnum >= SIDEBOLT1 && picnum <= SIDEBOLT1 + 3) + { + movesidebolt(i); + } + + else if (picnum >= pPick(BOLT1) && picnum <= pPick(BOLT1) + 3) + { + movebolt(i); + } + + else if (picnum == pPick(WATERDRIP)) + { + movewaterdrip(i); + } + + else if (picnum == pPick(DOORSHOCK)) + { + movedoorshock(i); + } + + else if (picnum == TOUCHPLATE) + { + movetouchplate(i); + } + + else if (isRR() ? picnum == RR_CANWITHSOMETHING : isIn(picnum, CANWITHSOMETHING, CANWITHSOMETHING2, CANWITHSOMETHING3, CANWITHSOMETHING4)) + { + movecanwithsomething(i); + } + + else if (!isRR() ? + isIn(picnum, + EXPLODINGBARREL, + WOODENHORSE, + HORSEONSIDE, + FLOORFLAME, + FIREBARREL, + FIREVASE, + NUKEBARREL, + NUKEBARRELDENTED, + NUKEBARRELLEAKED, + TOILETWATER, + RUBBERCAN, + STEAM, + CEILINGSTEAM, + WATERBUBBLEMAKER) : + isIn(picnum, + RR_1187, + RR_1196, + RR_1251, + RR_1268, + RR_1304, + RR_1305, + RR_1306, + RR_1315, + RR_1317, + RR_1388, + RR_STEAM, + RR_CEILINGSTEAM, + RR_WATERBUBBLEMAKER) + ) + { + int x; + int p = findplayer(s, &x); + execute(i, p, x); + } + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void bounce(int i) +{ + int k, l, daang, dax, day, daz, xvect, yvect, zvect; + short hitsect; + spritetype* s = &sprite[i]; + + xvect = mulscale10(s->xvel, sintable[(s->ang + 512) & 2047]); + yvect = mulscale10(s->xvel, sintable[s->ang & 2047]); + zvect = s->zvel; + + hitsect = s->sectnum; + + k = sector[hitsect].wallptr; l = wall[k].point2; + daang = getangle(wall[l].x - wall[k].x, wall[l].y - wall[k].y); + + if (s->z < (hittype[i].floorz + hittype[i].ceilingz) >> 1) + k = sector[hitsect].ceilingheinum; + else + k = sector[hitsect].floorheinum; + + dax = mulscale14(k, sintable[(daang) & 2047]); + day = mulscale14(k, sintable[(daang + 1536) & 2047]); + daz = 4096; + + k = xvect * dax + yvect * day + zvect * daz; + l = dax * dax + day * day + daz * daz; + if ((abs(k) >> 14) < l) + { + k = divscale17(k, l); + xvect -= mulscale16(dax, k); + yvect -= mulscale16(day, k); + zvect -= mulscale16(daz, k); + } + + s->zvel = zvect; + s->xvel = ksqrt(dmulscale8(xvect, xvect, yvect, yvect)); + s->ang = getangle(xvect, yvect); +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +static void movetongue(int i) +{ + spritetype* s = &sprite[i]; + + hittype[i].temp_data[0] = sintable[(hittype[i].temp_data[1]) & 2047] >> 9; + hittype[i].temp_data[1] += 32; + if (hittype[i].temp_data[1] > 2047) + { + deletesprite(i); + return; + } + + if (sprite[s->owner].statnum == MAXSTATUS) + if (badguy(&sprite[s->owner]) == 0) + { + deletesprite(i); + return; + } + + s->ang = sprite[s->owner].ang; + s->x = sprite[s->owner].x; + s->y = sprite[s->owner].y; + if (sprite[s->owner].picnum == APLAYER) + s->z = sprite[s->owner].z - (34 << 8); + for (int k = 0; k < hittype[i].temp_data[0]; k++) + { + int q = EGS(s->sectnum, + s->x + ((k * sintable[(s->ang + 512) & 2047]) >> 9), + s->y + ((k * sintable[s->ang & 2047]) >> 9), + s->z + ((k * ksgn(s->zvel)) * abs(s->zvel / 12)), pPick(TONGUE), -40 + (k << 1), + 8, 8, 0, 0, 0, i, 5); + sprite[q].cstat = 128; + sprite[q].pal = 8; + } + int k = hittype[i].temp_data[0]; // do not depend on the above loop counter. + int q = EGS(s->sectnum, + s->x + ((k * sintable[(s->ang + 512) & 2047]) >> 9), + s->y + ((k * sintable[s->ang & 2047]) >> 9), + s->z + ((k * ksgn(s->zvel)) * abs(s->zvel / 12)), pPick(INNERJAW), -40, + 32, 32, 0, 0, 0, i, 5); + sprite[q].cstat = 128; + if (hittype[i].temp_data[1] > 512 && hittype[i].temp_data[1] < (1024)) + sprite[q].picnum = pPick(INNERJAW) + 1; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void moveweapons(void) +{ + int j, k, nexti, p, q, tempsect; + int dax, day, daz, x, l, ll, x1, y1; + unsigned int qq; + spritetype* s; + + for (int i = headspritestat[STAT_PROJECTILE]; i >= 0; i = nexti) + { + nexti = nextspritestat[i]; + s = &sprite[i]; + int picnum = picnum; + + if (s->sectnum < 0) + { + deletesprite(i); + continue; + } + + hittype[i].bposx = s->x; + hittype[i].bposy = s->y; + hittype[i].bposz = s->z; + + if (picnum == pPick(RADIUSEXPLOSION) || (!isRR() && picnum == KNEE)) + { + deletesprite(i); + } + + else if (picnum == pPick(TONGUE)) + { + movetongue(i); + } + + else if (picnum == pPick2(FREEZEBLAST, RR_ALIENBLAST) && (s->yvel < 1 || s->extra < 2 || (s->xvel | s->zvel) == 0)) + { + j = spawn(i, pPick(TRANSPORTERSTAR)); + sprite[j].pal = 1; + sprite[j].xrepeat = 32; + sprite[j].yrepeat = 32; + deletesprite(i); + continue; + } + + else if (!isRR() ? + (isIn(picnum, FREEZEBLAST, SHRINKSPARK, RPG, FIRELASER, SPIT, COOLEXPLOSION1) || (isWorldTour() && picnum == FIREBALL)) : + (isIn(picnum, RR_ALIENBLAST, RR_CROSSBOW, RR_FIRELASER, RR_SHITBALL, RR_CIRCLESAW, RR_UWHIP, RR_OWHIP, RR_DILDO) || (isRRRA() && isIn(picnum, RR_CHIKENCROSSBOW, RR_1790))) + ) + { + if (!isRR() && picnum == COOLEXPLOSION1) + if (!S_CheckSoundPlaying(i, WIERDSHOT_FLY)) + A_PlaySound(WIERDSHOT_FLY, i); + + p = -1; + + if ((picnum == pPick2(RPG, RR_CROSSBOW) || (isRRRA() && picnum == RR_CHIKENCROSSBOW)) && sector[s->sectnum].lotag == 2) + { + k = s->xvel >> 1; + ll = s->zvel >> 1; + } + else + { + k = s->xvel; + ll = s->zvel; + } + + dax = s->x; day = s->y; daz = s->z; + + getglobalz(i); + qq = CLIPMASK1; + + if (picnum == pPick2(RPG, RR_CROSSBOW)) + { + if (hittype[i].picnum != pPick(BOSS2) && s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) + { + j = spawn(i, pPick(SMALLSMOKE)); + sprite[j].z += (1 << 8); + } + } + else if (isRRRA() && picnum == RR_CHIKENCROSSBOW) + { + s->hitag++; + if (hittype[i].picnum != RR_BOSS2 && s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) + { + j = spawn(i, RR_SMALLSMOKE); + sprite[j].z += (1 << 8); + if ((krand() & 15) == 2) + { + j = spawn(i, RR_1310); + } + } + if (sprite[s->lotag].extra <= 0) + s->lotag = 0; + if (s->lotag != 0 && s->hitag > 5) + { + spritetype* ts; + int ang, ang2, ang3; + ts = &sprite[s->lotag]; + ang = getangle(ts->x - s->x, ts->y - s->y); + ang2 = ang - s->ang; + ang3 = abs(ang2); + if (ang2 < 100) + { + if (ang3 > 1023) + s->ang += 51; + else + s->ang -= 51; + } + else if (ang2 > 100) + { + if (ang3 > 1023) + s->ang -= 51; + else + s->ang += 51; + } + else + s->ang = ang; + + if (s->hitag > 180) + if (s->zvel <= 0) + s->zvel += 200; + } + } + else if (isRRRA() && picnum == RR_1790) + { + if (s->extra) + { + s->zvel = -(s->extra * 250); + s->extra--; + } + else + makeitfall(i); + if (s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) + { + j = spawn(i, RR_SMALLSMOKE); + sprite[j].z += (1 << 8); + } + } + else if (isWorldTour() && picnum == FIREBALL) + { + if (sector[s->sectnum].lotag == 2) + { + deletesprite(i); + continue; + } + + if (sprite[s->owner].picnum != FIREBALL) + { + if (hittype[i].temp_data[0] >= 1 && hittype[i].temp_data[0] < 6) + { + float siz = 1.0f - (hittype[i].temp_data[0] * 0.2f); + int trail = hittype[i].temp_data[1]; + j = hittype[i].temp_data[1] = spawn(i, FIREBALL); + + auto spr = &sprite[j]; + spr->xvel = sprite[i].xvel; + spr->yvel = sprite[i].yvel; + spr->zvel = sprite[i].zvel; + if (hittype[i].temp_data[0] > 1) + { + FireProj* proj = fire.CheckKey(trail); + if (proj != nullptr) + { + spr->x = proj->x; + spr->y = proj->y; + spr->z = proj->z; + spr->xvel = proj->xv; + spr->yvel = proj->yv; + spr->zvel = proj->zv; + } + } + spr->yrepeat = spr->xrepeat = (short)(sprite[i].xrepeat * siz); + spr->cstat = sprite[i].cstat; + spr->extra = 0; + + FireProj proj = { spr->x, spr->y, spr->z, spr->xvel, spr->yvel, spr->zvel }; + fire.Insert(j, proj); + changespritestat((short)j, (short)4); + } + hittype[i].temp_data[0]++; + } + + if (s->zvel < 15000) + s->zvel += 200; + } + + j = movesprite(i, + (k * (sintable[(s->ang + 512) & 2047])) >> 14, + (k * (sintable[s->ang & 2047])) >> 14, ll, qq); + + if ((picnum == pPick2(RPG, RR_CROSSBOW) || (isRRRA() && isIn(picnum, RR_CHIKENCROSSBOW, RR_1790))) && s->yvel >= 0) + if (FindDistance2D(s->x - sprite[s->yvel].x, s->y - sprite[s->yvel].y) < 256) + j = 49152 | s->yvel; + + if (s->sectnum < 0) // || (isRR() && sector[s->sectnum].filler == 800)) + { + deletesprite(i); + continue; + } + + if ((j & 49152) != 49152) + if (picnum != pPick2(FREEZEBLAST, RR_ALIENBLAST)) + { + if (s->z < hittype[i].ceilingz) + { + j = 16384 | (s->sectnum); + s->zvel = -1; + } + else + if ((s->z > hittype[i].floorz && sector[s->sectnum].lotag != 1) || + (s->z > hittype[i].floorz + (16 << 8) && sector[s->sectnum].lotag == 1)) + { + j = 16384 | (s->sectnum); + if (sector[s->sectnum].lotag != 1) + s->zvel = 1; + } + } + + if (picnum == pPick(FIRELASER)) + { + for (k = -3; k < 2; k++) + { + x = EGS(s->sectnum, + s->x + ((k * sintable[(s->ang + 512) & 2047]) >> 9), + s->y + ((k * sintable[s->ang & 2047]) >> 9), + s->z + ((k * ksgn(s->zvel)) * klabs(s->zvel / 24)), pPick(FIRELASER), -40 + (k << 2), + s->xrepeat, s->yrepeat, 0, 0, 0, s->owner, 5); + + sprite[x].cstat = 128; + sprite[x].pal = s->pal; + } + } + else if (picnum == pPick2(SPIT, RR_SHITBALL)) if (s->zvel < 6144) + s->zvel += gc - 112; + + if (j != 0) + { + if (!isRR() && picnum == COOLEXPLOSION1) + { + if ((j & 49152) == 49152 && sprite[j & (MAXSPRITES - 1)].picnum != APLAYER) + { + continue; + } + s->xvel = 0; + s->zvel = 0; + } + + //if ((j & kHitTypeMask) == kHitSprite) j &= kHitIndexMask; reminder for later. + if ((j & 49152) == 49152) + { + j &= (MAXSPRITES - 1); + + if (isRRRA()) + { + if (sprite[j].picnum == RR_MINION + && (picnum == RR_CROSSBOW || picnum == RR_CHIKENCROSSBOW) + && sprite[j].pal == 19) + { + spritesound(RPG_EXPLODE, i); + j = spawn(i, RR_EXPLOSION2); + sprite[j].x = s->x; + sprite[j].y = s->y; + sprite[j].z = s->z; + continue; + } + } + else if (picnum == pPick2(FREEZEBLAST, RR_ALIENBLAST) && sprite[j].pal == 1) + if (badguy(&sprite[j]) || sprite[j].picnum == APLAYER) + { + j = spawn(i, pPick(TRANSPORTERSTAR)); + sprite[j].pal = 1; + sprite[j].xrepeat = 32; + sprite[j].yrepeat = 32; + + deletesprite(i); + continue; + } + + checkhitsprite(j, i); + + if (sprite[j].picnum == APLAYER) + { + p = sprite[j].yvel; + spritesound(PISTOL_BODYHIT, j); + + if (picnum == pPick2(SPIT, RR_SHITBALL)) + { + if (sprite[s->owner].picnum == RR_MAMAJACKOLOPE) + { + guts(s, RR_RABBITJIBA, 2, myconnectindex); + guts(s, RR_RABBITJIBB, 2, myconnectindex); + guts(s, RR_RABBITJIBC, 2, myconnectindex); + } + + ps[p].q16horiz += 32 << FRACBITS; + ps[p].return_to_center = 8; + + if (ps[p].loogcnt == 0) + { + if (!A_CheckSoundPlaying(ps[p].i, DUKE_LONGTERM_PAIN)) + A_PlaySound(DUKE_LONGTERM_PAIN, ps[p].i); + + j = 3 + (krand() & 3); + ps[p].numloogs = j; + ps[p].loogcnt = 24 * 4; + for (x = 0; x < j; x++) + { + ps[p].loogiex[x] = krand() % xdim; + ps[p].loogiey[x] = krand() % ydim; + } + } + } + } + } + else if ((j & 49152) == 32768) + { + j &= (MAXWALLS - 1); + + if (isRRRA() && sprite[s->owner].picnum == RR_MAMAJACKOLOPE) + { + guts(s, RR_RABBITJIBA, 2, myconnectindex); + guts(s, RR_RABBITJIBB, 2, myconnectindex); + guts(s, RR_RABBITJIBC, 2, myconnectindex); + } + + bool ismirror = (wall[j].overpicnum == pPick(MIRROR) || wall[j].picnum == pPick(MIRROR)); + if (ismirror && !isRR() ? + isIn(picnum, RPG, FREEZEBLAST, SPIT) : + (isIn(picnum, RR_CROSSBOW, RR_ALIENBLAST, RR_SHITBALL, RR_CIRCLESAW) || (isRRRA() && picnum == RR_CHIKENCROSSBOW)) + ) + { + 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; + s->owner = i; + spawn(i, pPick(TRANSPORTERSTAR)); + continue; + } + else + { + setsprite(i, dax, day, daz); + checkhitwall(i, j, s->x, s->y, s->z, picnum); + + if (!isRRRA() && picnum == pPick2(FREEZEBLAST, RR_ALIENBLAST)) + { + if (!ismirror) + { + s->extra >>= 1; + s->yvel--; + } + + 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; + continue; + } + + if (isRR() && s->picnum == RR_CIRCLESAW) + { + if (wall[j].picnum >= RR_3643 && wall[j].picnum < RR_3643 + 3) + { + deletesprite(i); + } + if (s->extra <= 0) + { + s->x += sintable[(s->ang + 512) & 2047] >> 7; + s->y += sintable[s->ang & 2047] >> 7; + if (!isRRRA() || (sprite[s->owner].picnum != RR_DAISYMAE && sprite[s->owner].picnum != RR_DAISYMAESTAYPUT)) + { + j = spawn(i, RR_CIRCLESTUCK); + sprite[j].xrepeat = 8; + sprite[j].yrepeat = 8; + sprite[j].cstat = 16; + sprite[j].ang = (sprite[j].ang + 512) & 2047; + sprite[j].clipdist = mulscale7(s->xrepeat, tilesiz[s->picnum].x); + } + deletesprite(i); + continue; + } + if (!ismirror) + { + s->extra -= 20; + s->yvel--; + } + + 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; + continue; + } + } + } + else if ((j & 49152) == 16384) + { + setsprite(i, dax, day, daz); + + if (isRRRA() && sprite[s->owner].picnum == RR_MAMAJACKOLOPE) + { + guts(s, RR_RABBITJIBA, 2, myconnectindex); + guts(s, RR_RABBITJIBB, 2, myconnectindex); + guts(s, RR_RABBITJIBC, 2, myconnectindex); + } + + if (s->zvel < 0) + { + if (sector[s->sectnum].ceilingstat & 1) + if (sector[s->sectnum].ceilingpal == 0) + { + deletesprite(i); + continue; + } + + checkhitceiling(s->sectnum); + } + + if (!isRRRA() && picnum == pPick2(FREEZEBLAST, RR_ALIENBLAST)) + { + bounce(i); + ssp(i, qq); + s->extra >>= 1; + if (s->xrepeat > 8) + s->xrepeat -= 2; + if (s->yrepeat > 8) + s->yrepeat -= 2; + s->yvel--; + continue; + } + } + + if (picnum != pPick2(SPIT, RR_SHITBALL)) + { + if (picnum == pPick2(RPG, RR_CROSSBOW)) + { + k = spawn(i, pPick(EXPLOSION2)); + sprite[k].x = dax; + sprite[k].y = day; + sprite[k].z = daz; + + if (s->xrepeat < 10) + { + sprite[k].xrepeat = 6; + sprite[k].yrepeat = 6; + } + else if ((j & 49152) == 16384) + { + if (!isRR() && s->zvel > 0) + spawn(i, EXPLOSION2BOT); + else { sprite[k].cstat |= 8; sprite[k].z += (48 << 8); } + } + } + else if (isRRRA() && s->picnum == RR_CHIKENCROSSBOW) + { + k = spawn(i, RR_EXPLOSION2); + sprite[k].x = dax; + sprite[k].y = day; + sprite[k].z = daz; + + if (s->xrepeat < 10) + { + sprite[k].xrepeat = 6; + sprite[k].yrepeat = 6; + } + else if ((j & 49152) == 16384) + { + sprite[k].cstat |= 8; + sprite[k].z += (48 << 8); + } + } + else if (isRRRA() && s->picnum == RR_1790) + { + s->extra = 160; + k = spawn(i, RR_EXPLOSION2); + sprite[k].x = dax; + sprite[k].y = day; + sprite[k].z = daz; + + if (s->xrepeat < 10) + { + sprite[k].xrepeat = 6; + sprite[k].yrepeat = 6; + } + else if ((j & 49152) == 16384) + { + sprite[k].cstat |= 8; + sprite[k].z += (48 << 8); + } + } + + else if (!isRR() && picnum == SHRINKSPARK) + { + spawn(i, SHRINKEREXPLOSION); + spritesound(SHRINKER_HIT, i); + hitradius(i, shrinkerblastradius, 0, 0, 0, 0); + } + else if (!isRR() ? + !isIn(picnum, COOLEXPLOSION1, FREEZEBLAST, FIRELASER) : + !isIn(picnum, RR_ALIENBLAST, RR_FIRELASER, RR_CIRCLESAW)) + { + k = spawn(i, pPick(EXPLOSION2)); + sprite[k].xrepeat = sprite[k].yrepeat = s->xrepeat >> 1; + if ((j & 49152) == 16384) + { + if (s->zvel < 0) + { + sprite[k].cstat |= 8; sprite[k].z += (72 << 8); + } + } + } + if (picnum == pPick2(RPG, RR_CROSSBOW)) + { + spritesound(RPG_EXPLODE, i); + + if (s->xrepeat >= 10) + { + x = s->extra; + hitradius(i, rpgblastradius, x >> 2, x >> 1, x - (x >> 2), x); + } + else + { + x = s->extra + (global_random & 3); + hitradius(i, (rpgblastradius >> 1), x >> 2, x >> 1, x - (x >> 2), x); + } + } + else if (isRRRA() && s->picnum == RR_CHIKENCROSSBOW) + { + s->extra = 150; + spritesound(247, i); + + if (s->xrepeat >= 10) + { + x = s->extra; + hitradius(i, rpgblastradius, x >> 2, x >> 1, x - (x >> 2), x); + } + else + { + x = s->extra + (global_random & 3); + hitradius(i, (rpgblastradius >> 1), x >> 2, x >> 1, x - (x >> 2), x); + } + } + else if (s->picnum == RR_1790) + { + s->extra = 160; + spritesound(RPG_EXPLODE, i); + + if (s->xrepeat >= 10) + { + x = s->extra; + hitradius(i, rpgblastradius, x >> 2, x >> 1, x - (x >> 2), x); + } + else + { + x = s->extra + (global_random & 3); + hitradius(i, (rpgblastradius >> 1), x >> 2, x >> 1, x - (x >> 2), x); + } + } + + } + if (isRR() || picnum != COOLEXPLOSION1) + { + deletesprite(i); + continue; + } + } + if (!isRR() && picnum == COOLEXPLOSION1) + { + s->shade++; + if (s->shade >= 40) + { + deletesprite(i); + continue; + } + } + else if ((picnum == pPick2(RPG, RR_CROSSBOW) || (isRRRA() && picnum == RR_CHIKENCROSSBOW)) && sector[s->sectnum].lotag == 2 && s->xrepeat >= 10 && rnd(140)) + spawn(i, pPick(WATERBUBBLE)); + + continue; + } + else if (picnum == pPick(SHOTSPARK1)) + { + p = findplayer(s, &x); + execute(i, p, x); + } + } +} + + + +END_DUKE_NS diff --git a/source/games/duke/src/actors_e.cpp b/source/games/duke/src/e_actors.cpp similarity index 100% rename from source/games/duke/src/actors_e.cpp rename to source/games/duke/src/e_actors.cpp diff --git a/source/games/duke/src/names.h b/source/games/duke/src/names.h index ec8add7d4..ef35e973e 100644 --- a/source/games/duke/src/names.h +++ b/source/games/duke/src/names.h @@ -775,436 +775,6 @@ enum DEVELOPERCOMMENTARY = 5294, BOSS5 = 5310, BOSS5STAYPUT = 5311, - - // Redneck Rampage - - RR_GRID = 0, - RR_JAILDOOR = 11, - RR_LNRDTAG = 15, - RR_SIGN1 = 16, - RR_SIGN2 = 17, - RR_TORCH = 18, - //FIRSTGUNSPRITE = 21, - RR_RIFLESPRITE = 22, - RR_CROSSBOWSPRITE = 23, - RR_TEATGUN = 24, - RR_BUZSAWSPRITE = 25, - RR_DYNAMITE = 26, - RR_POWDERKEGSPRITE = 27, - //SHOTGUNSPRITE = 28, - RR_ALIENARMGUN = 29, - //HEALTHBOX = 30, - //AMMOBOX = 31, - RR_TEATAMMO = 32, - //INVENTORYBOX = 33, - RR_DOORKEYS = 34, - RR_LIGHTNIN = 35, - RR_DESTRUCTO = 36, - RR_JAILSOUND = 38, - //AMMO = 40, - RR_RIFLEAMMO = 41, - RR_ALIENBLASTERAMMO = 42, - RR_BLADEAMMO = 43, - //HBOMBAMMO = 47, - //SHOTGUNAMMO = 49, - RR_BEER = 51, - RR_PORKBALLS = 52, - RR_WHISKEY = 53, - RR_MOONSHINE = 55, - RR_SNORKLE = 56, - RR_COWPIE = 57, - RR_DOORKEY = 60, - //BOOTS = 61, - RR_MINECARTKILLER = 67, - RR_SHADESECTOR = 68, - RR_SOUNDFX = 71, - RR_MULTISWITCH = 98, - RR_DOORSHOCK = 120, - RR_FLOORSLIME = 132, - RR_BIGFORCE = 135, - RR_SCREENBREAK6 = 164, - RR_SCREENBREAK7 = 165, - RR_SCREENBREAK8 = 166, - RR_FANSPRITEWORK = 210, - RR_FANSPRITE = 211, - RR_FANSPRITEBROKE = 215, - RR_GRATE1 = 234, - RR_BGRATE1 = 235, - RR_WATERDRIP = 239, - RR_WATERBUBBLE = 240, - RR_WATERBUBBLEMAKER = 241, - RR_W_FORCEFIELD = 242, - RR_LIGHTSWITCH2 = 250, - RR_UFOBEAM = 252, - RR_BOULDER = 256, - RR_BOULDER1 = 264, - RR_BOWLLINE = 280, - RR_CHICKENA = 285, - RR_CHICKENC = 286, - RR_HEADCHK = 287, - RR_FEATHERCHK = 288, - RR_LOAF = 289, - RR_NUGGETS = 290, - RR_PACKEDCHK = 291, - RR_BONELESSCHK = 292, - RR_JIBSCHK = 293, - RR_BIGFNTCURSOR = 512, - RR_SMALLFNTCURSOR = 513, - RR_STARTALPHANUM = 514, - RR_ENDALPHANUM = 607, - RR_BIGALPHANUM = 632, - RR_BIGPERIOD = 694, - RR_BIGCOMMA = 695, - RR_BIGX = 696, - RR_BIGQ = 697, - RR_BIGSEMI = 698, - RR_BIGCOLIN = 699, - RR_THREEBYFIVE = 702, - RR_BIGAPPOS = 714, - RR_MINIFONT = 718, - RR_RESPAWNMARKERRED = 866, - - RR_MOONSKY1 = 1022, - RR_MOONSKY2 = 1023, - RR_MOONSKY3 = 1024, - RR_MOONSKY4 = 1025, - RR_BIGORBIT1 = 1026, - RR_BIGORBIT2 = 1027, - RR_BIGORBIT3 = 1028, - RR_BIGORBIT4 = 1029, - RR_BIGORBIT5 =1030, - RR_WATERTILE2 = 1045, - RR_GLASS = 1056, - RR_GLASS2 = 1057, - RR_CRACK1 = 1075, - RR_CRACK2 = 1076, - RR_CRACK3 = 1077, - RR_CRACK4 = 1078, - RR_FOOTPRINTS = 1079, - RR_MIRROR = 1089, - RR_WATERFOUNTAIN = 1092, - RR_REACTOR = 1107, - RR_REACTORBURNT = 1108, - RR_REACTORSPARK = 1109, - RR_BOLT1 = 1127, - - - RR_CAMERA1 = 1134, - RR_FOOTPRINTS2 = 1144, - RR_FOOTPRINTS3 = 1145, - RR_FOOTPRINTS4 = 1146, - RR_SLIME = 1161, - RR_QUEBALL = 1184, - RR_STRIPEBALL = 1185, - RR_POCKET = 1186, - RR_AFLAM1191 = 1191, - RR_AFLAM1193 = 1193, - RR_NEON1 = 1200, - RR_NEON2 = 1201, - RR_BOUNCEMINE = 1204, - RR_BULLETHOLE = 1212, - RR_TIRE = 1230, - RR_NEON3 = 1241, - RR_NEON4 = 1242, - RR_NEON5 = 1243, - RR_GLASSPIECES = 1256, - RR_NEON6 = 1264, - RR_OOZFILTER = 1273, - RR_FLOORPLASMA = 1276, - RR_BOTTLE12 = 1282, - RR_BOTTLE13 = 1283, - RR_BOTTLE14 = 1284, - RR_BOTTLE15 = 1285, - RR_BOTTLE16 = 1286, - RR_BOTTLE17 = 1287, - RR_BOTTLE18 = 1288, - RR_VENDMACHINE = 1291, - RR_VENDMACHINEBROKE = 1293, - RR_COLAMACHINE = 1294, - RR_COLAMACHINEBROKE = 1296, - RR_CRANE = 1299, - RR_BLOODPOOL = 1303, - RR_CANWITHSOMETHING = 1309, - RR_FEATHERS = 1310, - RR_BANNER = 1313, - RR_SEENINE = 1324, - RR_SEENINEDEAD = 1325, - RR_STEAM = 1327, - RR_CEILINGSTEAM = 1332, - RR_TRANSPORTERBEAM = 1338, - RR_RAT = 1344, - RR_TRASH = 1346, - RR_WATERSPLASH2 = 1383, - RR_BLOOD = 1391, - RR_TRANSPORTERSTAR = 1398, - RR_ALIENBLAST = 1409, - RR_TONGUE = 1414, - RR_MORTER = 1416, - RR_MUD = 1420, - RR_RADIUSEXPLOSION = 1426, - RR_FORCERIPPLE = 1427, - RR_INNERJAW = 1439, - RR_EXPLOSION2 = 1441, - RR_EXPLOSION3 = 1442, - RR_JIBS1 = 1463, - RR_JIBS2 = 1468, - RR_JIBS3 = 1473, - RR_JIBS4 = 1478, - RR_JIBS5 = 1483, - RR_BURNING = 1494, - RR_FIRE = 1495, - RR_JIBS6 = 1515, - RR_BLOODSPLAT1 = 1525, - RR_BLOODSPLAT3 = 1526, - RR_BLOODSPLAT2 = 1527, - RR_BLOODSPLAT4 = 1528, - RR_OOZ = 1529, - RR_WALLBLOOD1 = 1530, - RR_WALLBLOOD2 = 1531, - RR_WALLBLOOD3 = 1532, - RR_WALLBLOOD4 = 1533, - RR_WALLBLOOD5 = 1534, - RR_WALLBLOOD6 = 1535, - RR_WALLBLOOD7 = 1536, - RR_WALLBLOOD8 = 1537, - RR_OOZ2 = 1538, - RR_BURNING2 = 1539, - RR_FIRE2 = 1540, - RR_SMALLSMOKE = 1554, - RR_SMALLSMOKEMAKER = 1555, - RR_SCRAP6 = 1595, - RR_SCRAP1 = 1605, - RR_SCRAP2 = 1609, - RR_SCRAP3 = 1613, - RR_SCRAP4 = 1617, - RR_SCRAP5 = 1621, - RR_F1HELP = 1633, - RR_MENUSCREEN = 1641, - RR_MENUBAR = 1642, - RR_KILLSICON = 1643, - RR_WHISHKEY_ICON = 1645, - RR_EMPTY_ICON = 1646, - RR_BOTTOMSTATUSBAR = 1647, - RR_BOOT_ICON = 1648, - RR_FRAGBAR = 1650, - RR_COWPIE_ICON = 1652, - RR_SNORKLE_ICON = 1653, - RR_MOONSHINE_ICON = 1654, - RR_BEER_ICON = 1655, - RR_ACCESS_ICON = 1656, - RR_DIGITALNUM = 1657, - RR_SLIDEBAR = 1674, - RR_WINDOWBORDER1 = 1679, - RR_TEXTBOX = 1680, - RR_WINDOWBORDER2 = 1681, - RR_INGAMELNRDTHREEDEE = 1684, - RR_TENSCREEN = 1685, - RR_NEWCROSSHAIR = 1689, - RR_CROSSHAIR = 1692, - RR_SHELL = 1702, - RR_SHOTGUNSHELL = 1704, - RR_FORCESPHERE = 1759, - RR_SHOTSPARK1 = 1764, - RR_CROSSBOW = 1774, - RR_TORNADO = 1930, - RR_TIKILAMP = 1990, - RR_POPCORN = 2021, - RR_TESLACON = 2056, - RR_TESLABALL = 2094, - RR_DILDO = 2095, - RR_TESLA = 2097, - RR_HURTRAIL = 2221, - RR_LOCKSWITCH1 = 2224, - RR_STATUEFLASH = 2231, - RR_REACTOR2 = 2239, - RR_REACTOR2SPARK = 2243, - RR_REACTOR2BURNT = 2247, - RR_EXPLOSION2BOT = 2272, - RR_SELECTDIR = 2444, - RR_VIEWBORDER = 2520, - RR_ORDERING = 2531, - RR_TEXTSTORY = 2541, - RR_LOADSCREEN = 2542, - RR_STARSKY2 = 2577, - RR_SPINNINGNUKEICON = 896, - RR_TOILETPAPER = 2864, - RR_BUSTAWIN5A = 2878, - RR_BUSTAWIN5B = 2879, - RR_BUSTAWIN4A = 2898, - RR_BUSTAWIN4B = 2899, - RR_FRAMEEFFECT1 = 2999, - - RR_AFLAM3062 = 3062, - - RR_LOAFTILE = 3120, - RR_NUGGETTILE = 3122, - RR_BROASTEDTILE = 3123, - RR_BONELESSTILE = 3124, - RR_HEAD1TILE = 3132, - RR_HEAD2TILE = 3133, - RR_CHICKENATILE = 3190, - RR_CHICKENBTILE = 3191, - RR_CHICKENCTILE = 3192, - - RR_NEWPISTOL = 3328, - RR_NEWPISTOLCOCK = 3336, - RR_NEWCROWBAR = 3340, - RR_CROWBAR = RR_NEWCROWBAR, - RR_NEWSHOTGUN = 3350, - RR_SHOTGUN = RR_NEWSHOTGUN, - RR_NEWDYNAMITE = 3360, - RR_RIFLE = 3380, - RR_CIRCLESTUCK = 3388, - RR_SHITBALL = 3390, - RR_BUZSAW = 3395, - RR_CIRCLESAW = 3400, - RR_LUMBERBLADE = 3411, - RR_FIRELASER = 3420, - RR_BOWLINGBALL = 3430, - RR_BOWLINGBALLSPRITE = 3437, - RR_CHEERBOMB = -3464, - RR_OWHIP = 3471, - RR_UWHIP = 3475, - RR_BACKGROUND = 3822, - RR_APLAYERTOP = 3840, - RR_APLAYER = 3845, - RR_PLAYERONWATER = 3860, - RR_LNYDLADDER = 3975, - RR_LNRDLYINGDEAD = 3998, - RR_LNRDGUN = 4041, - RR_LNRDTORSO = 4046, - RR_LNRLEG = 4055, - RR_DOGATTACK = 4060, - RR_BILLYWALK = 4096, - RR_BILLYDIE = 4137, - RR_BILLYCOCK = 4147, - RR_BILLYRAY = 4162, - RR_BILLYSHOOT = 4162, - RR_BILLYRAYSTAYPUT = 4163, - RR_BILLYBUT = 4188, - RR_BILLYSCRATCH = 4191, - RR_BILLYSNIFF = 4195, - RR_BILLYWOUND = 4202, - RR_BILLYGORE = 4228, - RR_BILLYJIBA = 4235, - RR_BILLYJIBB = 4244, - RR_DOGRUN = 4260, - RR_DOGDIE = 4295, - RR_DOGDEAD = 4303, - RR_DOGBARK = 4305, - RR_LTH = 4352, - RR_LTHSTRAFE = 4395, - RR_LTHLOAD = 4430, - RR_LTHDIE = 4456, - RR_BUBBASCRATCH = 4464, - RR_BUBBANOSE = 4476, - RR_BUBBAPISS = 4487, - RR_BUBBASTAND = 4504, - RR_BUBBAOUCH = 4506, - RR_BUBBADIE = 4513, - RR_BUBBADEAD = 4523, - RR_BOSS2 = 4557, - RR_HULK = 4649, - RR_HULKSTAYPUT = 4650, - RR_HULKA = 4651, - RR_HULKB = 4652, - RR_HULKC = 4653, - RR_HULKJIBA = 4748, - RR_HULKJIBB = 4753, - RR_HULKJIBC = 4758, - RR_SBSWIPE = 4770, - RR_SBPAIN = 4810, - RR_SBDIE = 4820, - RR_HEN = 4861, - RR_HENSTAYPUT = 4862, - RR_HENSTAND = 4897, - RR_MOSQUITO = 4916, - RR_PIG = 4945, - RR_PIGSTAYPUT = 4946, - RR_PIGEAT = 4983, - RR_SBMOVE = 5015, - RR_SBSPIT = 5050, - RR_SBDIP = 5085, - RR_MINION = 5120, - RR_MINIONSTAYPUT = 5121, - RR_UFO1 = 5270, - RR_UFO2 = 5274, - RR_UFO3 = 5278, - RR_UFO4 = 5282, - RR_UFO5 = 5286, - RR_MINJIBA = 5290, - RR_MINJIBB = 5295, - RR_MINJIBC = 5300, - RR_COW = 5317, - RR_COOT = 5376, - RR_COOTSTAYPUT = 5377, - RR_COOTSHOOT = 5411, - RR_COOTDIE = 5437, - RR_COOTDUCK = 5481, - RR_COOTPAIN = 5548, - RR_COOTTRANS = 5568, - RR_COOTGETUP = 5579, - RR_ECLAIRHEALTH = 5595, - RR_COOTJIBA = 5602, - RR_COOTJIBB = 5607, - RR_COOTJIBC = 5616, - RR_VIXEN = 5635, - RR_VIXENPAIN = 5675, - RR_VIXENDIE = 5710, - RR_VIXENSHOOT = 5720, - RR_VIXENWDN = 5740, - RR_VIXENWUP = 5775, - RR_VIXENKICK = 5805, - RR_VIXENTELE = 5845, - RR_VIXENTEAT = 5851, - RR_BIKERBV = 5891, - RR_MAKEOUT = 6225, - RR_CHEER = 6658, - RR_CHEERSTAYPUT = 6659, - //RA - RR_AIRPLANE = 8450, - RR_SWAMPBUGGY = 7233, - RR_MOTORCYCLE = 7220, - RR_CHIKENCROSSBOW = 1781, - RR_BIKERSTAND = 5995, - RR_BIKERRIDE = 5890, - RR_BIKERRIDEDAISY = 6401, - RR_MINIONAIRBOAT = 7192, - RR_HULKAIRBOAT = 7199, - RR_DAISYMAE = 6658, - RR_DAISYMAESTAYPUT = 6659, - RR_DAISYAIRBOAT = 7206, - RR_MINIONUFO = 5260, - RR_JACKOLOPE = 7280, - RR_BANJOCOOTER = 7030, - RR_GUITARBILLY = 7035, - RR_MAMACLOUD = 8663, - RR_MAMAJACKOLOPE = 8705, - RR_RABBITJIBA = 7387, - RR_RABBITJIBB = 7392, - RR_RABBITJIBC = 7397, - - // Stuff that gets referenced but has no name. RR Reconstruction only has Duke names for these items which should be avoided. - RR_1196 = 1196, - RR_1251 = 1251, - RR_1268 = 1268, - RR_1187 = 1187, - RR_1304 = 1304, - RR_1305 = 1305, - RR_1306 = 1306, - RR_1309 = 1309, - RR_1310 = 1310, - RR_1315 = 1315, - RR_1317 = 1317, - RR_1388 = 1388, - RR_3440 = 3440, - RR_1228 = 1228, - RR_1273 = 1273, - RR_4989 = 4989, - RR_1790 = 1790, - RR_3643 = 3643, - - }; extern int APLAYER; diff --git a/source/games/duke/src/names_rr.h b/source/games/duke/src/names_rr.h new file mode 100644 index 000000000..778687e9c --- /dev/null +++ b/source/games/duke/src/names_rr.h @@ -0,0 +1,1409 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 1996, 2003 - 3D Realms Entertainment +Copyright (C) 2017-2019 Nuke.YKT + +This file is part of Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms +*/ +//------------------------------------------------------------------------- + + +#pragma once + +BEGIN_DUKE_NS + +enum +{ + SECTOREFFECTOR = 1, + ACTIVATOR = 2, + TOUCHPLATE = 3, + ACTIVATORLOCKED = 4, + MUSICANDSFX = 5, + LOCATORS = 6, + CYCLER = 7, + MASTERSWITCH = 8, + RESPAWN = 9, + GPSPEED = 10, + RRTILE11 = 11, + PLEASEWAIT = 12, + FOF = 13, + //WEATHERWARN = 14, + RPG2SPRITE = 14, + DUKETAG = 15, + SIGN1 = 16, + SIGN2 = 17, + RRTILE18 = 18, + RRTILE19 = 19, + ARROW = 20, + FIRSTGUNSPRITE = 21, + CHAINGUNSPRITE = 22, + RPGSPRITE = 23, + FREEZESPRITE = 24, + SHRINKERSPRITE = 25, + HEAVYHBOMB = 26, + TRIPBOMBSPRITE = 27, + SHOTGUNSPRITE = 28, + DEVISTATORSPRITE = 29, + HEALTHBOX = 30, + AMMOBOX = 31, + GROWSPRITEICON = 32, + INVENTORYBOX = 33, + RRTILE34 = 34, + RRTILE35 = 35, + DESTRUCTO = 36, + FREEZEAMMO = 37, + RRTILE38 = 38, + AMMO = 40, + BATTERYAMMO = 41, + DEVISTATORAMMO = 42, + RRTILE43 = 43, + RPGAMMO = 44, + GROWAMMO = 45, + CRYSTALAMMO = 46, + HBOMBAMMO = 47, + AMMOLOTS = 48, + SHOTGUNAMMO = 49, + COLA = 51, + SIXPAK = 52, + FIRSTAID = 53, + SHIELD = 54, + STEROIDS = 55, + AIRTANK = 56, + JETPACK = 57, + HEATSENSOR = 59, + ACCESSCARD = 60, + BOOTS = 61, + GUTMETER = 62, + RRTILE63 = 63, + RRTILE64 = 64, + RRTILE65 = 65, + RRTILE66 = 66, + RRTILE67 = 67, + RRTILE68 = 68, + MIRRORBROKE = 70, + SOUNDFX = 71, + TECHLIGHT2 = 72, + TECHLIGHTBUST2 = 73, + TECHLIGHT4 = 74, + TECHLIGHTBUST4 = 75, + WALLLIGHT4 = 76, + WALLLIGHTBUST4 = 77, + MOTOAMMO = 78, + BUTTON1 = 80, + ACCESSSWITCH = 82, + SLOTDOOR = 84, + LIGHTSWITCH = 86, + SPACEDOORSWITCH = 88, + SPACELIGHTSWITCH = 90, + FRANKENSTINESWITCH = 92, + NUKEBUTTON = 94, + MULTISWITCH = 98, + DOORTILE1 = 102, + DOORTILE2 = 103, + DOORTILE3 = 104, + DOORTILE4 = 105, + DOORTILE5 = 106, + DOORTILE6 = 107, + DOORTILE7 = 108, + DOORTILE8 = 109, + DOORTILE9 = 110, + DOORTILE10 = 111, + DOORTILE14 = 115, + DOORTILE15 = 116, + DOORTILE16 = 117, + DOORTILE18 = 119, + DOORSHOCK = 120, + DIPSWITCH = 121, + DIPSWITCH2 = 123, + TECHSWITCH = 125, + DIPSWITCH3 = 127, + ACCESSSWITCH2 = 129, + REFLECTWATERTILE = 131, + FLOORSLIME = 132, + BIGFORCE = 135, + EPISODE = 137, + MASKWALL1 = 138, + MASKWALL2 = 140, + MASKWALL3 = 141, + MASKWALL4 = 142, + MASKWALL5 = 143, + MASKWALL6 = 144, + MASKWALL8 = 146, + MASKWALL9 = 147, + MASKWALL10 = 148, + MASKWALL11 = 149, + MASKWALL12 = 150, + MASKWALL13 = 151, + MASKWALL14 = 152, + MASKWALL15 = 153, + FIREEXT = 155, + W_LIGHT = 156, + SCREENBREAK1 = 159, + SCREENBREAK2 = 160, + SCREENBREAK3 = 161, + SCREENBREAK4 = 162, + SCREENBREAK5 = 163, + SCREENBREAK6 = 164, + SCREENBREAK7 = 165, + SCREENBREAK8 = 166, + SCREENBREAK9 = 167, + SCREENBREAK10 = 168, + SCREENBREAK11 = 169, + SCREENBREAK12 = 170, + SCREENBREAK13 = 171, + W_TECHWALL1 = 185, + W_TECHWALL2 = 186, + W_TECHWALL3 = 187, + W_TECHWALL4 = 188, + W_TECHWALL10 = 189, + W_TECHWALL15 = 191, + W_TECHWALL16 = 192, + STATIC = 195, + W_SCREENBREAK = 199, + W_HITTECHWALL3 = 205, + W_HITTECHWALL4 = 206, + W_HITTECHWALL2 = 207, + W_HITTECHWALL1 = 208, + FANSPRITE = 210, + FANSPRITEBROKE = 215, + FANSHADOW = 216, + FANSHADOWBROKE = 219, + DOORTILE19 = 229, + DOORTILE20 = 230, + DOORTILE22 = 232, + GRATE1 = 234, + BGRATE1 = 235, + SPLINTERWOOD = 237, + WATERDRIP = 239, + WATERBUBBLE = 240, + WATERBUBBLEMAKER = 241, + W_FORCEFIELD = 242, + WALLLIGHT3 = 244, + WALLLIGHTBUST3 = 245, + WALLLIGHT1 = 246, + WALLLIGHTBUST1 = 247, + WALLLIGHT2 = 248, + WALLLIGHTBUST2 = 249, + LIGHTSWITCH2 = 250, + UFOBEAM = 252, + RRTILE280 = 280, + RRTILE281 = 281, + RRTILE282 = 282, + RRTILE283 = 283, + RRTILE285 = 285, + RRTILE286 = 286, + RRTILE287 = 287, + RRTILE288 = 288, + RRTILE289 = 289, + RRTILE290 = 290, + RRTILE291 = 291, + RRTILE292 = 292, + RRTILE293 = 293, + RRTILE295 = 295, + RRTILE296 = 296, + RRTILE297 = 297, + CDPLAYER = 370, + RRTILE380 = 380, + RRTILE403 = 403, + RRTILE409 = 409, + BIGFNTCURSOR = 512, + SMALLFNTCURSOR = 513, + STARTALPHANUM = 514, + ENDALPHANUM = 607, + BIGALPHANUM = 632, + BIGPERIOD = 694, + BIGCOMMA = 695, + BIGX = 696, + BIGQ = 697, + BIGSEMI = 698, + BIGCOLIN = 699, + THREEBYFIVE = 702, + BIGAPPOS = 714, + MINIFONT = 718, + W_NUMBERS = 810, + BLANK = 820, + RESPAWNMARKERRED = 866, + RESPAWNMARKERYELLOW = 876, + RESPAWNMARKERGREEN = 886, + SPINNINGNUKEICON = 896, + GUTMETER_LIGHT1 = 920, + GUTMETER_LIGHT2 = 921, + GUTMETER_LIGHT3 = 922, + GUTMETER_LIGHT4 = 923, + AMMO_ICON = 930, + CLOUDYSKIES = 1021, + MOONSKY1 = 1022, + MOONSKY2 = 1023, + MOONSKY3 = 1024, + MOONSKY4 = 1025, + BIGORBIT1 = 1026, + BIGORBIT2 = 1027, + BIGORBIT3 = 1028, + BIGORBIT4 = 1029, + BIGORBIT5 = 1030, + LA = 1031, + REDSKY1 = 1040, + REDSKY2 = 1041, + WATERTILE = 1044, + WATERTILE2 = 1045, + SATELLITE = 1049, + VIEWSCREEN2 = 1052, + VIEWSCREENBROKE = 1054, + VIEWSCREEN = 1055, + GLASS = 1056, + GLASS2 = 1057, + STAINGLASS1 = 1063, + SATELITE = 1066, + FUELPOD = 1067, + SLIMEPIPE = 1070, + CRACK1 = 1075, + CRACK2 = 1076, + CRACK3 = 1077, + CRACK4 = 1078, + FOOTPRINTS = 1079, + DOMELITE = 1080, + CAMERAPOLE = 1083, + CHAIR1 = 1085, + CHAIR2 = 1086, + BROKENCHAIR = 1088, + MIRROR = 1089, + WATERFOUNTAIN = 1092, + WATERFOUNTAINBROKE = 1096, + FEMMAG1 = 1097, + TOILET = 1098, + STALL = 1100, + STALLBROKE = 1102, + FEMMAG2 = 1106, + REACTOR2 = 1107, + REACTOR2BURNT = 1108, + REACTOR2SPARK = 1109, + SOLARPANNEL = 1114, + NAKED1 = 1115, + ANTENNA = 1117, + TOILETBROKE = 1120, + PIPE2 = 1121, + PIPE1B = 1122, + PIPE3 = 1123, + PIPE1 = 1124, + PIPE2B = 1126, + BOLT1 = 1127, + PIPE3B = 1132, + CAMERA1 = 1134, + BRICK = 1139, + VACUUM = 1141, + JURYGUY = 1142, + FOOTPRINTS2 = 1144, + FOOTPRINTS3 = 1145, + FOOTPRINTS4 = 1146, + EGG = 1147, + SCALE = 1150, + CHAIR3 = 1152, + CAMERALIGHT = 1157, + MOVIECAMERA = 1158, + FOOTPRINT = 1160, + IVUNIT = 1163, + POT1 = 1164, + POT2 = 1165, + POT3 = 1166, + STATUE = 1168, + MIKE = 1170, + VASE = 1172, + SUSHIPLATE1 = 1174, + SUSHIPLATE2 = 1175, + SUSHIPLATE3 = 1176, + SUSHIPLATE4 = 1178, + SUSHIPLATE5 = 1180, + BIGHOLE2 = 1182, + STRIPEBALL = 1184, + QUEBALL = 1185, + POCKET = 1186, + WOODENHORSE = 1187, + TREE1 = 1191, + TREE2 = 1193, + CACTUS = 1194, + TOILETWATER = 1196, + NEON1 = 1200, + NEON2 = 1201, + CACTUSBROKE = 1203, + BOUNCEMINE = 1204, + BROKEFIREHYDRENT = 1210, + BOX = 1211, + BULLETHOLE = 1212, + BOTTLE1 = 1215, + BOTTLE2 = 1216, + BOTTLE3 = 1217, + BOTTLE4 = 1218, + BOTTLE5 = 1219, + BOTTLE6 = 1220, + BOTTLE7 = 1221, + BOTTLE8 = 1222, + SNAKEP = 1224, + DOLPHIN1 = 1225, + DOLPHIN2 = 1226, + HYDRENT = 1228, + TIRE = 1230, + PIPE5 = 1232, + PIPE6 = 1233, + PIPE4 = 1234, + PIPE4B = 1235, + BROKEHYDROPLANT = 1237, + PIPE5B = 1239, + NEON3 = 1241, + NEON4 = 1242, + NEON5 = 1243, + SPOTLITE = 1247, + HANGOOZ = 1249, + HORSEONSIDE = 1251, + GLASSPIECES = 1256, + HORSELITE = 1259, + DONUTS = 1263, + NEON6 = 1264, + CLOCK = 1266, + RUBBERCAN = 1268, + BROKENCLOCK = 1270, + PLUG = 1272, + OOZFILTER = 1273, + FLOORPLASMA = 1276, + HANDPRINTSWITCH = 1278, + BOTTLE10 = 1280, + BOTTLE11 = 1281, + BOTTLE12 = 1282, + BOTTLE13 = 1283, + BOTTLE14 = 1284, + BOTTLE15 = 1285, + BOTTLE16 = 1286, + BOTTLE17 = 1287, + BOTTLE18 = 1288, + BOTTLE19 = 1289, + VENDMACHINE = 1291, + VENDMACHINEBROKE = 1293, + COLAMACHINE = 1294, + COLAMACHINEBROKE = 1296, + CRANEPOLE = 1298, + CRANE = 1299, + BARBROKE = 1302, + BLOODPOOL = 1303, + NUKEBARREL = 1304, + NUKEBARRELDENTED = 1305, + NUKEBARRELLEAKED = 1306, + CANWITHSOMETHING = 1309, + MONEY = 1310, + BANNER = 1313, + EXPLODINGBARREL = 1315, + EXPLODINGBARREL2 = 1316, + FIREBARREL = 1317, + SEENINE = 1324, + SEENINEDEAD = 1325, + STEAM = 1327, + CEILINGSTEAM = 1332, + PIPE6B = 1337, + TRANSPORTERBEAM = 1338, + RAT = 1344, + TRASH = 1346, + HELECOPT = 1348, + FETUSJIB = 1349, + HOLODUKE = 1350, + MONK = 1354, + SPACEMARINE = 1355, + LUKE = 1356, + INDY = 1357, + FETUS = 1360, + FETUSBROKE = 1361, + WATERSPLASH2 = 1383, + FIREVASE = 1388, + SCRATCH = 1389, + BLOOD = 1391, + TRANSPORTERSTAR = 1398, + LOOGIE = 1405, + FIST = 1408, + FREEZEBLAST = 1409, + DEVISTATORBLAST = 1410, + TONGUE = 1414, + MORTER = 1416, + MUD = 1420, + SHRINKEREXPLOSION = 1421, + RADIUSEXPLOSION = 1426, + FORCERIPPLE = 1427, + CANNONBALL = 1437, + INNERJAW = 1439, + EXPLOSION2 = 1441, + EXPLOSION3 = 1442, + JIBS1 = 1463, + JIBS2 = 1468, + JIBS3 = 1473, + JIBS4 = 1478, + JIBS5 = 1483, + CRACKKNUCKLES = 1489, + HEADERBAR = 1493, + BURNING = 1494, + FIRE = 1495, + USERWEAPON = 1510, + JIBS6 = 1515, + BLOODSPLAT1 = 1525, + BLOODSPLAT3 = 1526, + BLOODSPLAT2 = 1527, + BLOODSPLAT4 = 1528, + OOZ = 1529, + WALLBLOOD1 = 1530, + WALLBLOOD2 = 1531, + WALLBLOOD3 = 1532, + WALLBLOOD4 = 1533, + WALLBLOOD5 = 1534, + WALLBLOOD6 = 1535, + WALLBLOOD7 = 1536, + WALLBLOOD8 = 1537, + OOZ2 = 1538, + BURNING2 = 1539, + FIRE2 = 1540, + SMALLSMOKE = 1554, + SMALLSMOKEMAKER = 1555, + FLOORFLAME = 1558, + GREENSLIME = 1575, + WATERDRIPSPLASH = 1585, + SCRAP6 = 1595, + SCRAP1 = 1605, + SCRAP2 = 1609, + SCRAP3 = 1613, + SCRAP4 = 1617, + SCRAP5 = 1621, + ROTATEGUN = 1624, + BETAVERSION = 1629, + PLAYERISHERE = 1630, + PLAYERWASHERE = 1631, + SELECTDIR = 1632, + F1HELP = 1633, + NOTCHON = 1634, + NOTCHOFF = 1635, + RRTILE1636 = 1636, + DUKEICON = 1637, + BADGUYICON = 1638, + FOODICON = 1639, + GETICON = 1640, + MENUSCREEN = 1641, + MENUBAR = 1642, + KILLSICON = 1643, + FIRSTAID_ICON = 1645, + HEAT_ICON = 1646, + BOTTOMSTATUSBAR = 1647, + BOOT_ICON = 1648, + WEAPONBAR = 1649, + FRAGBAR = 1650, + JETPACK_ICON = 1652, + AIRTANK_ICON = 1653, + STEROIDS_ICON = 1654, + HOLODUKE_ICON = 1655, + ACCESS_ICON = 1656, + DIGITALNUM = 1657, + CAMCORNER = 1667, + CAMLIGHT = 1669, + LOGO = 1670, + TITLE = 1671, + NUKEWARNINGICON = 1672, + MOUSECURSOR = 1673, + SLIDEBAR = 1674, + DUKECAR = 1676, + DREALMS = 1677, + BETASCREEN = 1678, + WINDOWBORDER1 = 1679, + TEXTBOX = 1680, + WINDOWBORDER2 = 1681, + DUKENUKEM = 1682, + THREEDEE = 1683, + INGAMEDUKETHREEDEE = 1684, + TENSCREEN = 1685, + PLUTOPAKSPRITE = 1686, + CROSSHAIR = 1689, + FALLINGCLIP = 1699, + CLIPINHAND = 1700, + HAND = 1701, + SHELL = 1702, + SHOTGUNSHELL = 1704, + RPGMUZZLEFLASH = 1714, + CATLITE = 1721, + HANDHOLDINGLASER = 1732, + TRIPBOMB = 1735, + LASERLINE = 1736, + HANDHOLDINGACCESS = 1737, + HANDREMOTE = 1739, + TIP = 1745, + GLAIR = 1747, + SPACEMASK = 1753, + RRTILE1752 = 1752, + FORCESPHERE = 1759, + SHOTSPARK1 = 1764, + RPG = 1774, + RPG2 = 1781, + // = LASERSITE = 1781, + RRTILE1790 = 1790, + RRTILE1792 = 1792, + RRTILE1801 = 1801, + RRTILE1805 = 1805, + RRTILE1807 = 1807, + RRTILE1808 = 1808, + RRTILE1812 = 1812, + RRTILE1814 = 1814, + RRTILE1817 = 1817, + RRTILE1821 = 1821, + RRTILE1824 = 1824, + RRTILE1826 = 1826, + RRTILE1850 = 1850, + RRTILE1851 = 1851, + RRTILE1856 = 1856, + RRTILE1877 = 1877, + RRTILE1878 = 1878, + RRTILE1938 = 1938, + RRTILE1939 = 1939, + RRTILE1942 = 1942, + RRTILE1944 = 1944, + RRTILE1945 = 1945, + RRTILE1947 = 1947, + RRTILE1951 = 1951, + RRTILE1952 = 1952, + RRTILE1953 = 1953, + RRTILE1961 = 1961, + RRTILE1964 = 1964, + RRTILE1973 = 1973, + RRTILE1985 = 1985, + RRTILE1986 = 1986, + RRTILE1987 = 1987, + RRTILE1988 = 1988, + RRTILE1990 = 1990, + RRTILE1995 = 1995, + RRTILE1996 = 1996, + RRTILE2004 = 2004, + RRTILE2005 = 2005, + POPCORN = 2021, + RRTILE2022 = 2022, + LANEPICS = 2023, + RRTILE2025 = 2025, + RRTILE2026 = 2026, + RRTILE2027 = 2027, + RRTILE2028 = 2028, + RRTILE2034 = 2034, + RRTILE2050 = 2050, + RRTILE2052 = 2052, + RRTILE2053 = 2053, + RRTILE2056 = 2056, + RRTILE2060 = 2060, + RRTILE2072 = 2072, + RRTILE2074 = 2074, + RRTILE2075 = 2075, + RRTILE2083 = 2083, + COOLEXPLOSION1 = 2095, + RRTILE2097 = 2097, + RRTILE2121 = 2121, + RRTILE2122 = 2122, + RRTILE2123 = 2123, + RRTILE2124 = 2124, + RRTILE2125 = 2125, + RRTILE2126 = 2126, + RRTILE2137 = 2137, + RRTILE2132 = 2132, + RRTILE2136 = 2136, + RRTILE2139 = 2139, + RRTILE2150 = 2150, + RRTILE2151 = 2151, + RRTILE2152 = 2152, + RRTILE2156 = 2156, + RRTILE2157 = 2157, + RRTILE2158 = 2158, + RRTILE2159 = 2159, + RRTILE2160 = 2160, + RRTILE2161 = 2161, + RRTILE2175 = 2175, + RRTILE2176 = 2176, + RRTILE2178 = 2178, + RRTILE2186 = 2186, + RRTILE2214 = 2214, + WAITTOBESEATED = 2215, + OJ = 2217, + HURTRAIL = 2221, + POWERSWITCH1 = 2222, + LOCKSWITCH1 = 2224, + POWERSWITCH2 = 2226, + ATM = 2229, + STATUEFLASH = 2231, + ATMBROKE = 2233, + FEMPIC5 = 2235, + FEMPIC6 = 2236, + FEMPIC7 = 2237, + REACTOR = 2239, + REACTORSPARK = 2243, + REACTORBURNT = 2247, + HANDSWITCH = 2249, + CIRCLEPANNEL = 2251, + CIRCLEPANNELBROKE = 2252, + PULLSWITCH = 2254, + ALIENSWITCH = 2259, + DOORTILE21 = 2261, + DOORTILE17 = 2263, + MASKWALL7 = 2264, + JAILBARBREAK = 2265, + DOORTILE11 = 2267, + DOORTILE12 = 2268, + EXPLOSION2BOT = 2272, + RRTILE2319 = 2319, + RRTILE2321 = 2321, + RRTILE2326 = 2326, + RRTILE2329 = 2329, + RRTILE2357 = 2357, + RRTILE2382 = 2382, + RRTILE2430 = 2430, + RRTILE2431 = 2431, + RRTILE2432 = 2432, + RRTILE2437 = 2437, + RRTILE2443 = 2443, + RRTILE2445 = 2445, + RRTILE2446 = 2446, + RRTILE2450 = 2450, + RRTILE2451 = 2451, + RRTILE2455 = 2455, + RRTILE2460 = 2460, + RRTILE2465 = 2465, + BONUSSCREEN = 2510, + VIEWBORDER = 2520, + VICTORY1 = 2530, + ORDERING = 2531, + TEXTSTORY = 2541, + LOADSCREEN = 2542, + RRTILE2560 = 2560, + RRTILE2562 = 2562, + RRTILE2564 = 2564, + RRTILE2573 = 2573, + RRTILE2574 = 2574, + RRTILE2577 = 2577, + RRTILE2578 = 2578, + RRTILE2581 = 2581, + RRTILE2583 = 2583, + RRTILE2604 = 2604, + RRTILE2610 = 2610, + RRTILE2613 = 2613, + RRTILE2621 = 2621, + RRTILE2622 = 2622, + RRTILE2636 = 2636, + RRTILE2637 = 2637, + RRTILE2654 = 2654, + RRTILE2656 = 2656, + RRTILE2676 = 2676, + RRTILE2689 = 2689, + RRTILE2697 = 2697, + RRTILE2702 = 2702, + RRTILE2707 = 2707, + RRTILE2732 = 2732, + HATRACK = 2717, + DESKLAMP = 2719, + COFFEEMACHINE = 2721, + CUPS = 2722, + GAVALS = 2723, + GAVALS2 = 2724, + POLICELIGHTPOLE = 2726, + FLOORBASKET = 2728, + PUKE = 2729, + DOORTILE23 = 2731, + TOPSECRET = 2733, + SPEAKER = 2734, + TEDDYBEAR = 2735, + ROBOTDOG = 2737, + ROBOTPIRATE = 2739, + ROBOTMOUSE = 2740, + MAIL = 2741, + MAILBAG = 2742, + HOTMEAT = 2744, + COFFEEMUG = 2745, + DONUTS2 = 2746, + TRIPODCAMERA = 2747, + METER = 2748, + DESKPHONE = 2749, + GUMBALLMACHINE = 2750, + GUMBALLMACHINEBROKE = 2751, + PAPER = 2752, + MACE = 2753, + GENERICPOLE2 = 2754, + XXXSTACY = 2755, + WETFLOOR = 2756, + BROOM = 2757, + MOP = 2758, + PIRATE1A = 2759, + PIRATE4A = 2760, + PIRATE2A = 2761, + PIRATE5A = 2762, + PIRATE3A = 2763, + PIRATE6A = 2764, + PIRATEHALF = 2765, + CHESTOFGOLD = 2767, + SIDEBOLT1 = 2768, + FOODOBJECT1 = 2773, + FOODOBJECT2 = 2774, + FOODOBJECT3 = 2775, + FOODOBJECT4 = 2776, + FOODOBJECT5 = 2777, + FOODOBJECT6 = 2778, + FOODOBJECT7 = 2779, + FOODOBJECT8 = 2780, + FOODOBJECT9 = 2781, + FOODOBJECT10 = 2782, + FOODOBJECT11 = 2783, + FOODOBJECT12 = 2784, + FOODOBJECT13 = 2785, + FOODOBJECT14 = 2786, + FOODOBJECT15 = 2787, + FOODOBJECT16 = 2788, + FOODOBJECT17 = 2789, + FOODOBJECT18 = 2790, + FOODOBJECT19 = 2791, + FOODOBJECT20 = 2792, + HEADLAMP = 2793, + SKINNEDCHICKEN = 2794, + FEATHEREDCHICKEN = 2795, + TAMPON = 2796, + ROBOTDOG2 = 2797, + JOLLYMEAL = 2800, + DUKEBURGER = 2801, + SHOPPINGCART = 2806, + CANWITHSOMETHING2 = 2807, + CANWITHSOMETHING3 = 2808, + CANWITHSOMETHING4 = 2809, + RRTILE2030 = 2030, + RRTILE2831 = 2831, + RRTILE2832 = 2832, + RRTILE2842 = 2842, + RRTILE2859 = 2859, + RRTILE2876 = 2876, + RRTILE2878 = 2878, + RRTILE2879 = 2879, + RRTILE2893 = 2893, + RRTILE2894 = 2894, + RRTILE2898 = 2898, + RRTILE2899 = 2899, + RRTILE2915 = 2915, + RRTILE2940 = 2940, + RRTILE2944 = 2944, + RRTILE2945 = 2945, + RRTILE2946 = 2946, + RRTILE2947 = 2947, + RRTILE2948 = 2948, + RRTILE2949 = 2949, + RRTILE2961 = 2961, + RRTILE2970 = 2970, + RRTILE2977 = 2977, + RRTILE2978 = 2978, + GLASS3 = 2983, + BORNTOBEWILDSCREEN = 2985, + BLIMP = 2989, + RRTILE2990 = 2990, + FEM9 = 2991, + POOP = 2998, + FRAMEEFFECT1 = 2999, + PANNEL1 = 3003, + PANNEL2 = 3004, + PANNEL3 = 3005, + BPANNEL1 = 3006, + BPANNEL3 = 3007, + SCREENBREAK14 = 3008, + SCREENBREAK15 = 3009, + SCREENBREAK19 = 3011, + SCREENBREAK16 = 3013, + SCREENBREAK17 = 3014, + SCREENBREAK18 = 3015, + W_TECHWALL11 = 3016, + W_TECHWALL12 = 3017, + W_TECHWALL13 = 3018, + W_TECHWALL14 = 3019, + W_TECHWALL5 = 3020, + W_TECHWALL6 = 3022, + W_TECHWALL7 = 3024, + W_TECHWALL8 = 3026, + W_TECHWALL9 = 3028, + W_HITTECHWALL16 = 3030, + W_HITTECHWALL10 = 3031, + W_HITTECHWALL15 = 3033, + W_MILKSHELF = 3035, + W_MILKSHELFBROKE = 3036, + PURPLELAVA = 3038, + LAVABUBBLE = 3040, + DUKECUTOUT = 3047, + TARGET = 3049, + GUNPOWDERBARREL = 3050, + DUCK = 3051, + HYDROPLANT = 3053, + OCEANSPRITE1 = 3055, + OCEANSPRITE2 = 3056, + OCEANSPRITE3 = 3057, + OCEANSPRITE4 = 3058, + OCEANSPRITE5 = 3059, + GENERICPOLE = 3061, + CONE = 3062, + HANGLIGHT = 3063, + RRTILE3073 = 3073, + RRTILE3083 = 3083, + RRTILE3100 = 3100, + RRTILE3114 = 3114, + RRTILE3115 = 3115, + RRTILE3116 = 3116, + RRTILE3117 = 3117, + RRTILE3120 = 3120, + RRTILE3121 = 3121, + RRTILE3122 = 3122, + RRTILE3123 = 3123, + RRTILE3124 = 3124, + RRTILE3132 = 3132, + RRTILE3139 = 3139, + RRTILE3144 = 3144, + RRTILE3152 = 3152, + RRTILE3153 = 3153, + RRTILE3155 = 3155, + RRTILE3171 = 3171, + RRTILE3172 = 3172, + RRTILE3190 = 3190, + RRTILE3191 = 3191, + RRTILE3192 = 3192, + RRTILE3195 = 3195, + RRTILE3200 = 3200, + RRTILE3201 = 3201, + RRTILE3202 = 3202, + RRTILE3203 = 3203, + RRTILE3204 = 3204, + RRTILE3205 = 3205, + RRTILE3206 = 3206, + RRTILE3207 = 3207, + RRTILE3208 = 3208, + RRTILE3209 = 3209, + RRTILE3216 = 3216, + RRTILE3218 = 3218, + RRTILE3219 = 3219, + RRTILE3232 = 3232, + FEMPIC1 = 3239, + FEMPIC2 = 3248, + BLANKSCREEN = 3252, + PODFEM1 = 3253, + FEMPIC3 = 3257, + FEMPIC4 = 3265, + FEM1 = 3271, + FEM2 = 3276, + FEM3 = 3280, + FEM5 = 3282, + BLOODYPOLE = 3283, + FEM4 = 3284, + FEM6 = 3293, + FEM6PAD = 3294, + FEM8 = 3295, + FEM7 = 3298, + ORGANTIC = 3308, + FIRSTGUN = 3328, + FIRSTGUNRELOAD = 3336, + KNEE = 3340, + SHOTGUN = 3350, + HANDTHROW = 3360, + SHOTGUNSHELLS = 3372, + SCUBAMASK = 3374, + CHAINGUN = 3380, + SHRINKER = 3384, + CIRCLESTUCK = 3388, + SPIT = 3390, + GROWSPARK = 3395, + SHRINKSPARK = 3400, + RRTILE3410 = 3410, + LUMBERBLADE = 3411, + FREEZE = 3415, + FIRELASER = 3420, + BOWLINGBALLH = 3428, + BOWLINGBALL = 3430, + BOWLINGBALLSPRITE = 3437, + POWDERH = 3438, + RRTILE3440 = 3440, + DEVISTATOR = 3445, + RPGGUN = 3452, + RRTILE3462 = 3462, + OWHIP = 3471, + UWHIP = 3475, + RPGGUN2 = 3482, + RRTILE3497 = 3497, + RRTILE3498 = 3498, + RRTILE3499 = 3499, + RRTILE3500 = 3500, + SLINGBLADE = 3510, + RRTILE3584 = 3584, + RRTILE3586 = 3586, + RRTILE3587 = 3587, + RRTILE3600 = 3600, + RRTILE3631 = 3631, + RRTILE3635 = 3635, + RRTILE3637 = 3637, + RRTILE3643 = 3643, + RRTILE3647 = 3647, + RRTILE3652 = 3652, + RRTILE3653 = 3653, + RRTILE3668 = 3668, + RRTILE3671 = 3671, + RRTILE3673 = 3673, + RRTILE3684 = 3684, + RRTILE3708 = 3708, + RRTILE3714 = 3714, + RRTILE3716 = 3716, + RRTILE3720 = 3720, + RRTILE3723 = 3723, + RRTILE3725 = 3725, + RRTILE3737 = 3737, + RRTILE3754 = 3754, + RRTILE3762 = 3762, + RRTILE3763 = 3763, + RRTILE3764 = 3764, + RRTILE3765 = 3765, + RRTILE3767 = 3767, + RRTILE3773 = 3773, + RRTILE3774 = 3774, + RRTILE3793 = 3793, + RRTILE3795 = 3795, + RRTILE3804 = 3804, + RRTILE3814 = 3814, + RRTILE3815 = 3815, + RRTILE3819 = 3819, + BIGHOLE = 3822, + RRTILE3827 = 3827, + RRTILE3837 = 3837, + APLAYERTOP = 3840, + APLAYER = 3845, + PLAYERONWATER = 3860, + DUKELYINGDEAD = 3998, + DUKEGUN = 4041, + DUKETORSO = 4046, + DUKELEG = 4055, + FECES = 4802, + DRONE = 4916, + //RRTILE4956 = 4956, + RECON = 4989, + RRTILE5014 = 5014, + RRTILE5016 = 5016, + RRTILE5017 = 5017, + RRTILE5018 = 5018, + RRTILE5019 = 5019, + RRTILE5020 = 5020, + RRTILE5021 = 5021, + RRTILE5022 = 5022, + RRTILE5023 = 5023, + RRTILE5024 = 5024, + RRTILE5025 = 5025, + RRTILE5026 = 5026, + RRTILE5027 = 5027, + RRTILE5029 = 5029, + RRTILE5030 = 5030, + RRTILE5031 = 5031, + RRTILE5032 = 5032, + RRTILE5033 = 5033, + RRTILE5034 = 5034, + RRTILE5035 = 5035, + RRTILE5036 = 5036, + RRTILE5037 = 5037, + RRTILE5038 = 5038, + RRTILE5039 = 5039, + RRTILE5040 = 5040, + RRTILE5041 = 5041, + RRTILE5043 = 5043, + RRTILE5044 = 5044, + RRTILE5045 = 5045, + RRTILE5046 = 5046, + RRTILE5047 = 5047, + RRTILE5048 = 5048, + RRTILE5049 = 5049, + RRTILE5050 = 5050, + RRTILE5051 = 5051, + RRTILE5052 = 5052, + RRTILE5053 = 5053, + RRTILE5054 = 5054, + RRTILE5055 = 5055, + RRTILE5056 = 5056, + RRTILE5057 = 5057, + RRTILE5058 = 5058, + RRTILE5059 = 5059, + RRTILE5061 = 5061, + RRTILE5062 = 5062, + RRTILE5063 = 5063, + RRTILE5064 = 5064, + RRTILE5065 = 5065, + RRTILE5066 = 5066, + RRTILE5067 = 5067, + RRTILE5068 = 5068, + RRTILE5069 = 5069, + RRTILE5070 = 5070, + RRTILE5071 = 5071, + RRTILE5072 = 5072, + RRTILE5073 = 5073, + RRTILE5074 = 5074, + RRTILE5075 = 5075, + RRTILE5076 = 5076, + RRTILE5077 = 5077, + RRTILE5078 = 5078, + RRTILE5079 = 5079, + RRTILE5080 = 5080, + RRTILE5081 = 5081, + RRTILE5082 = 5082, + RRTILE5083 = 5083, + RRTILE5084 = 5084, + RRTILE5085 = 5085, + RRTILE5086 = 5086, + RRTILE5087 = 5087, + RRTILE5088 = 5088, + RRTILE5090 = 5090, + SHARK = 5501, + FEM10 = 5581, + TOUGHGAL = 5583, + MAN = 5588, + MAN2 = 5589, + WOMAN = 5591, + ATOMICHEALTH = 5595, + RRTILE6144 = 6144, + MOTOGUN = 7168, + RRTILE7169 = 7169, + MOTOHIT = 7170, + BOATHIT = 7175, + RRTILE7184 = 7184, + RRTILE7190 = 7190, + RRTILE7191 = 7191, + RRTILE7213 = 7213, + RRTILE7219 = 7219, + EMPTYBIKE = 7220, + EMPTYBOAT = 7233, + RRTILE7424 = 7424, + RRTILE7430 = 7430, + RRTILE7433 = 7433, + RRTILE7441 = 7441, + RRTILE7547 = 7547, + RRTILE7467 = 7467, + RRTILE7469 = 7469, + RRTILE7470 = 7470, + RRTILE7475 = 7475, + RRTILE7478 = 7478, + RRTILE7505 = 7505, + RRTILE7506 = 7506, + RRTILE7534 = 7534, + RRTILE7540 = 7540, + RRTILE7533 = 7533, + RRTILE7545 = 7545, + RRTILE7552 = 7552, + RRTILE7553 = 7553, + RRTILE7554 = 7554, + RRTILE7555 = 7555, + RRTILE7557 = 7557, + RRTILE7558 = 7558, + RRTILE7559 = 7559, + RRTILE7561 = 7561, + RRTILE7566 = 7566, + RRTILE7568 = 7568, + RRTILE7574 = 7574, + RRTILE7575 = 7575, + RRTILE7576 = 7576, + RRTILE7578 = 7578, + RRTILE7579 = 7579, + RRTILE7580 = 7580, + RRTILE7595 = 7595, + RRTILE7629 = 7629, + RRTILE7636 = 7636, + RRTILE7638 = 7638, + RRTILE7640 = 7640, + RRTILE7644 = 7644, + RRTILE7646 = 7646, + RRTILE7648 = 7648, + RRTILE7650 = 7650, + RRTILE7653 = 7653, + RRTILE7655 = 7655, + RRTILE7657 = 7657, + RRTILE7659 = 7659, + RRTILE7691 = 7691, + RRTILE7694 = 7694, + RRTILE7696 = 7696, + RRTILE7697 = 7697, + RRTILE7700 = 7700, + RRTILE7702 = 7702, + RRTILE7704 = 7704, + RRTILE7705 = 7705, + RRTILE7711 = 7711, + RRTILE7716 = 7716, + RRTILE7756 = 7756, + RRTILE7768 = 7768, + RRTILE7806 = 7806, + RRTILE7820 = 7820, + RRTILE7859 = 7859, + RRTILE7870 = 7870, + RRTILE7873 = 7873, + RRTILE7875 = 7875, + RRTILE7876 = 7876, + RRTILE7879 = 7879, + RRTILE7881 = 7881, + RRTILE7883 = 7883, + RRTILE7885 = 7885, + RRTILE7886 = 7886, + RRTILE7887 = 7887, + RRTILE7888 = 7888, + RRTILE7889 = 7889, + RRTILE7890 = 7890, + RRTILE7900 = 7900, + RRTILE7901 = 7901, + RRTILE7906 = 7906, + RRTILE7912 = 7912, + RRTILE7913 = 7913, + RRTILE7936 = 7936, + RRTILE8047 = 8047, + MULTISWITCH2 = 8048, + RRTILE8059 = 8059, + RRTILE8060 = 8060, + RRTILE8063 = 8063, + RRTILE8067 = 8067, + RRTILE8076 = 8076, + RRTILE8094 = 8094, + RRTILE8096 = 8096, + RRTILE8099 = 8099, + RRTILE8106 = 8106, + RRTILE8162 = 8162, + RRTILE8163 = 8163, + RRTILE8164 = 8164, + RRTILE8165 = 8165, + RRTILE8166 = 8166, + RRTILE8167 = 8167, + RRTILE8168 = 8168, + RRTILE8192 = 8192, + RRTILE8193 = 8193, + RRTILE8215 = 8215, + RRTILE8216 = 8216, + RRTILE8217 = 8217, + RRTILE8218 = 8218, + RRTILE8220 = 8220, + RRTILE8221 = 8221, + RRTILE8222 = 8222, + RRTILE8223 = 8223, + RRTILE8224 = 8224, + RRTILE8227 = 8227, + RRTILE8312 = 8312, + RRTILE8370 = 8370, + RRTILE8371 = 8371, + RRTILE8372 = 8372, + RRTILE8373 = 8373, + RRTILE8379 = 8379, + RRTILE8380 = 8380, + RRTILE8385 = 8385, + RRTILE8386 = 8386, + RRTILE8387 = 8387, + RRTILE8388 = 8388, + RRTILE8389 = 8389, + RRTILE8390 = 8390, + RRTILE8391 = 8391, + RRTILE8392 = 8392, + RRTILE8394 = 8394, + RRTILE8395 = 8395, + RRTILE8396 = 8396, + RRTILE8397 = 8397, + RRTILE8398 = 8398, + RRTILE8399 = 8399, + RRTILE8423 = 8423, + RRTILE8448 = 8448, + RRTILE8450 = 8450, + BOATAMMO = 8460, + RRTILE8461 = 8461, + RRTILE8462 = 8462, + RRTILE8464 = 8464, + RRTILE8475 = 8475, + RRTILE8487 = 8487, + RRTILE8488 = 8488, + RRTILE8489 = 8489, + RRTILE8490 = 8490, + RRTILE8496 = 8496, + RRTILE8497 = 8497, + RRTILE8498 = 8498, + RRTILE8499 = 8499, + RRTILE8503 = 8503, + RRTILE8525 = 8525, + RRTILE8537 = 8537, + RRTILE8565 = 8565, + RRTILE8567 = 8567, + RRTILE8568 = 8568, + RRTILE8569 = 8569, + RRTILE8570 = 8570, + RRTILE8571 = 8571, + RRTILE8579 = 8579, + RRTILE8588 = 8588, + RRTILE8589 = 8589, + RRTILE8590 = 8590, + RRTILE8591 = 8591, + RRTILE8592 = 8592, + RRTILE8593 = 8593, + RRTILE8594 = 8594, + RRTILE8595 = 8595, + RRTILE8596 = 8596, + RRTILE8598 = 8598 = , + RRTILE8605 = 8605, + RRTILE8608 = 8608, + RRTILE8609 = 8609, + RRTILE8611 = 8611, + RRTILE8617 = 8617, + RRTILE8618 = 8618, + RRTILE8620 = 8620, + RRTILE8621 = 8621, + RRTILE8622 = 8622, + RRTILE8623 = 8623, + RRTILE8640 = 8640, + RRTILE8651 = 8651, + RRTILE8660 = 8660, + RRTILE8677 = 8677, + RRTILE8679 = 8679, + RRTILE8680 = 8680, + RRTILE8681 = 8681, + RRTILE8682 = 8682, + RRTILE8683 = 8683, + RRTILE8704 = 8704, + , + , + // = RR = bad = guys, + BOSS1 = 4477, + BOSS2 = 4557, + BOSS3 = 4607, + BOSS4 = 4221, + , + , + BOULDER = 256, + BOULDER1 = 264, + TORNADO = 1930, + CHEERBOMB = 3464, + CHEERBLADE = 3460, + DOGATTACK = 4060, + BILLYWALK = 4096, + BILLYDIE = 4137, + BILLYCOCK = 4147, + BILLYRAY = 4162, + BILLYRAYSTAYPUT = 4163, + BILLYBUT = 4188, + BILLYSCRATCH = 4191, + BILLYSNIFF = 4195, + BILLYWOUND = 4202, + BILLYGORE = 4228, + BILLYJIBA = 4235, + BILLYJIBB = 4244, + BRAYSNIPER = 4249, + DOGRUN = 4260, + DOGDIE = 4295, + DOGDEAD = 4303, + DOGBARK = 4305, + LTH = 4352, + LTHSTRAFE = 4395, + HULKHANG = 4409, + HULKHANGDEAD = 4410, + HULKJUMP = 4429, + LTHLOAD = 4430, + LTHDIE = 4456, + BUBBASCRATCH = 4464, + BUBBANOSE = 4476, + BUBBAPISS = 4487, + BUBBASTAND = 4504, + BUBBAOUCH = 4506, + BUBBADIE = 4513, + BUBBADEAD = 4523, + HULK = 4649, + HULKSTAYPUT = 4650, + HULKA = 4651, + HULKB = 4652, + HULKC = 4653, + HULKJIBA = 4748, + HULKJIBB = 4753, + HULKJIBC = 4758, + SBSWIPE = 4770, + SBPAIN = 4810, + SBDIE = 4820, + HEN = 4861, + HENSTAYPUT = 4862, + HENSTAND = 4897, + PIG = 4945, + PIGSTAYPUT = 4946, + PIGEAT = 4983, + SBMOVE = 5015, + SBSPIT = 5050, + SBDIP = 5085, + MINION = 5120, + MINIONSTAYPUT = 5121, + , + #ifdef = RRRA, + # = define = UFO1 = 5260, + #else, + # = define = UFO1 = 5270, + #endif, + , + UFO2 = 5274, + UFO3 = 5278, + UFO4 = 5282, + UFO5 = 5286, + MINJIBA = 5290, + MINJIBB = 5295, + MINJIBC = 5300, + COW = 5317, + COOT = 5376, + COOTSTAYPUT = 5377, + COOTSHOOT = 5411, + COOTDIE = 5437, + COOTDUCK = 5481, + COOTPAIN = 5548, + COOTTRANS = 5568, + COOTGETUP = 5579, + COOTJIBA = 5602, + COOTJIBB = 5607, + COOTJIBC = 5616, + VIXEN = 5635, + VIXENPAIN = 5675, + VIXENDIE = 5710, + VIXENSHOOT = 5720, + VIXENWDN = 5740, + VIXENWUP = 5775, + VIXENKICK = 5805, + VIXENTELE = 5845, + VIXENTEAT = 5851, + BIKEJIBA = 5872, + BIKEJIBB = 5877, + BIKEJIBC = 5882, + BIKERB = 5890, + BIKERBV2 = 5891, + BIKER = 5995, + BIKERJIBA = 6112, + BIKERJIBB = 6117, + BIKERJIBC = 6121, + BIKERJIBD = 6127, + MAKEOUT = 6225, + CHEERB = 6401, + CHEER = 6658, + CHEERSTAYPUT = 6659, + CHEERJIBA = 7000, + CHEERJIBB = 7005, + CHEERJIBC = 7010, + CHEERJIBD = 7015, + FBOATJIBA = 7020, + FBOATJIBB = 7025, + COOTPLAY = 7030, + BILLYPLAY = 7035, + MINIONBOAT = 7192, + HULKBOAT = 7199, + CHEERBOAT = 7206, + RRTILE7274 = 7274, + RABBIT = 7280, + RABBITJIBA = 7387, + RABBITJIBB = 7392, + RABBITJIBC = 7397, + ROCK = 8035, + ROCK2 = 8036, + MAMACLOUD = 8663, + MAMA = 8705, + MAMAJIBA = 8890, + MAMAJIBB = 8895, +}; \ No newline at end of file