//------------------------------------------------------------------------- /* Copyright (C) 1997, 2005 - 3D Realms Entertainment This file is part of Shadow Warrior version 1.2 Shadow Warrior 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Original Source: 1997 - Frank Maddin and Jim Norwood Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms */ //------------------------------------------------------------------------- #include "ns.h" #include "build.h" #include "names2.h" #include "game.h" #include "tags.h" #include "weapon.h" #include "sprite.h" //#include "ai.h" BEGIN_SW_NS SECTOR_OBJECTp DetectSectorObjectByWall(WALLp); void SOwallmove(SECTOR_OBJECTp sop, SPRITEp sp, WALLp find_wallp, int dist, int *nx, int *ny) { int j,k,wallcount; WALLp wp; short startwall,endwall; SECTORp *sectp; if (TEST(sop->flags, SOBJ_SPRITE_OBJ)) return; wallcount = 0; for (sectp = sop->sectp, j = 0; *sectp; sectp++, j++) { startwall = (*sectp)->wallptr; endwall = startwall + (*sectp)->wallnum - 1; // move all walls in sectors back to the original position for (wp = &wall[startwall], k = startwall; k <= endwall; wp++, k++) { // find the one wall we want to adjust if (wp == find_wallp) { short ang; // move orig x and y in saved angle ASSERT(User[sp - sprite].Data()); ang = User[sp - sprite]->sang; *nx = MulScale(dist, bcos(ang), 14); *ny = MulScale(dist, bsin(ang), 14); sop->xorig[wallcount] -= *nx; sop->yorig[wallcount] -= *ny; SET(sop->flags, SOBJ_UPDATE_ONCE); return; } wallcount++; } } } int DoWallMove(SPRITEp sp) { int dist,nx,ny; short shade1,shade2,ang,picnum1,picnum2; WALLp wallp; short prev_wall; bool found = false; short dang; bool SOsprite = false; dist = SP_TAG13(sp); ang = SP_TAG4(sp); picnum1 = SP_TAG5(sp); picnum2 = SP_TAG6(sp); shade1 = SP_TAG7(sp); shade2 = SP_TAG8(sp); dang = ((int)SP_TAG10(sp)) << 3; if (dang) ang = NORM_ANGLE(ang + (RANDOM_RANGE(dang) - dang/2)); nx = MulScale(dist, bcos(ang), 14); ny = MulScale(dist, bsin(ang), 14); for (wallp = wall; wallp < &wall[numwalls]; wallp++) { if (wallp->x == sp->x && wallp->y == sp->y) { found = true; if (TEST(wallp->extra, WALLFX_SECTOR_OBJECT)) { SECTOR_OBJECTp sop; sop = DetectSectorObjectByWall(wallp); ASSERT(sop); SOwallmove(sop, sp, wallp, dist, &nx, &ny); SOsprite = true; } else { wallp->x = sp->x + nx; wallp->y = sp->y + ny; sector[wallp->sector].dirty = 255; } if (shade1) wallp->shade = int8_t(shade1); if (picnum1) wallp->picnum = picnum1; // find the previous wall prev_wall = PrevWall(short(wallp - wall)); if (shade2) wall[prev_wall].shade = int8_t(shade2); if (picnum2) wall[prev_wall].picnum = picnum2; } } SP_TAG9(sp)--; if ((signed char)SP_TAG9(sp) <= 0) { KillSprite(short(sp - sprite)); } else { if (SOsprite) { // move the sprite offset from center User[sp - sprite]->sx -= nx; User[sp - sprite]->sy -= ny; } else { sp->x += nx; sp->y += ny; } } return found; } bool CanSeeWallMove(SPRITEp wp, short match) { int i; bool found = false; SPRITEp sp; StatIterator it(STAT_WALL_MOVE_CANSEE); while ((i = it.NextIndex()) >= 0) { sp = &sprite[i]; if (SP_TAG2(sp) == match) { found = true; if (cansee(wp->x,wp->y,wp->z,wp->sectnum,sp->x,sp->y,sp->z,sp->sectnum)) { return true; } } } if (found) return false; else return true; } int DoWallMoveMatch(short match) { SPRITEp sp; int i; bool found = false; // just all with the same matching tags StatIterator it(STAT_WALL_MOVE); while ((i = it.NextIndex()) >= 0) { sp = &sprite[i]; if (SP_TAG2(sp) == match) { found = true; DoWallMove(sp); } } return found; } #include "saveable.h" static saveable_code saveable_wallmove_code[] = { SAVE_CODE(DoWallMove), SAVE_CODE(CanSeeWallMove), SAVE_CODE(DoWallMoveMatch), }; saveable_module saveable_wallmove = { // code saveable_wallmove_code, SIZ(saveable_wallmove_code), // data nullptr,0 }; END_SW_NS