//------------------------------------------------------------------------- /* 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 "misc.h" #include "interpso.h" #include "render.h" BEGIN_SW_NS extern int GlobSpeedSO; void CopySectorWalls(sectortype* dest_sect, sectortype* src_sect) { SECTOR_OBJECTp sop; SECTORp *sectp; auto dwall = dest_sect->firstWall(); auto swall = src_sect->firstWall(); auto firstwall = dwall; // this looks broken. do { dwall->picnum = swall->picnum; dwall->xrepeat = swall->xrepeat; dwall->yrepeat = swall->yrepeat; dwall->overpicnum = swall->overpicnum; dwall->pal = swall->pal; dwall->cstat = swall->cstat; dwall->shade = swall->shade; dwall->xpan_ = swall->xpan_; dwall->ypan_ = swall->ypan_; dwall->hitag = swall->hitag; dwall->lotag = swall->lotag; dwall->extra = swall->extra; if (dwall->twoSided() && swall->twoSided()) { auto const dest_nextwall = dwall->nextWall(); auto const src_nextwall = swall->nextWall(); dest_nextwall->picnum = src_nextwall->picnum; dest_nextwall->xrepeat = src_nextwall->xrepeat; dest_nextwall->yrepeat = src_nextwall->yrepeat; dest_nextwall->overpicnum = src_nextwall->overpicnum; dest_nextwall->pal = src_nextwall->pal; dest_nextwall->cstat = src_nextwall->cstat; dest_nextwall->shade = src_nextwall->shade; dest_nextwall->xpan_ = src_nextwall->xpan_; dest_nextwall->ypan_ = src_nextwall->ypan_; dest_nextwall->hitag = src_nextwall->hitag; dest_nextwall->lotag = src_nextwall->lotag; dest_nextwall->extra = src_nextwall->extra; } dwall = dwall->point2Wall(); swall = swall->point2Wall(); } while (dwall != firstwall); // TODO: Mapping a sector to the sector object to which it belongs is better for (sop = SectorObject; sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++) { if (SO_EMPTY(sop)) continue; for (sectp = sop->sectp; *sectp; sectp++) if (*sectp == dest_sect) { so_setinterpolationtics(sop, 0); break; } } } void CopySectorMatch(int match) { SPRITEp dest_sp, src_sp; SECTORp dsectp,ssectp; int kill; SPRITEp k; SWStatIterator it(STAT_COPY_DEST); while (auto dActor = it.Next()) { dest_sp = &dActor->s(); dsectp = dest_sp->sector(); if (match != dest_sp->lotag) continue; SWStatIterator it2(STAT_COPY_SOURCE); while (auto sActor = it2.Next()) { src_sp = &sActor->s(); if (SP_TAG2(src_sp) == SP_TAG2(dest_sp) && SP_TAG3(src_sp) == SP_TAG3(dest_sp)) { ssectp = src_sp->sector(); // !!!!!AAAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHHHHHHH // Don't kill anything you don't have to // this wall killing things on a Queue causing // invalid situations #if 1 // kill all sprites in the dest sector that need to be SWSectIterator itsec(dsectp); while (auto itActor = itsec.Next()) { k = &itActor->s(); // kill anything not invisible if (!TEST(k->cstat, CSTAT_SPRITE_INVISIBLE)) { if (itActor->hasU()) { // be safe with the killing //SetSuicide(kill); } else { SpriteQueueDelete(itActor); // new function to allow killing - hopefully KillActor(itActor); } } } #endif CopySectorWalls(dsectp, ssectp); itsec.Reset(ssectp); while (auto itActor = itsec.Next()) { auto sp = &itActor->s(); // don't move ST1 Copy Tags if (SP_TAG1(sp) != SECT_COPY_SOURCE) { int sx,sy,dx,dy,src_xoff,src_yoff,trash; // move sprites from source to dest - use center offset // get center of src and dest sect SectorMidPoint(src_sp->sectnum, &sx, &sy, &trash); SectorMidPoint(dest_sp->sectnum, &dx, &dy, &trash); // get offset src_xoff = sx - sp->x; src_yoff = sy - sp->y; // move sprite to dest sector sp->x = dx - src_xoff; sp->y = dy - src_yoff; // change sector ChangeActorSect(itActor, dsectp); // check to see if it moved on to a sector object if (TEST(dsectp->extra, SECTFX_SECTOR_OBJECT)) { SECTOR_OBJECTp sop; // find and add sprite to SO sop = DetectSectorObject(sp->sector()); AddSpriteToSectorObject(itActor, sop); // update sprites postions so they aren't in the // wrong place for one frame GlobSpeedSO = 0; RefreshPoints(sop, 0, 0, true); } } } // copy sector user if there is one dsectp->flags = ssectp->flags; dsectp->depth_fixed = ssectp->depth_fixed; dsectp->stag = ssectp->stag; dsectp->ang = ssectp->ang; dsectp->height = ssectp->height; dsectp->speed = ssectp->speed; dsectp->damage = ssectp->damage; dsectp->number = ssectp->number; dsectp->u_defined = ssectp->u_defined; dsectp->flags2 = ssectp->flags2; dsectp->hitag = ssectp->hitag; dsectp->lotag = ssectp->lotag; dsectp->floorz = ssectp->floorz; dsectp->ceilingz = ssectp->ceilingz; dsectp->floorshade = ssectp->floorshade; dsectp->ceilingshade = ssectp->ceilingshade; dsectp->floorpicnum = ssectp->floorpicnum; dsectp->ceilingpicnum = ssectp->ceilingpicnum; dsectp->floorheinum = ssectp->floorheinum; dsectp->ceilingheinum = ssectp->ceilingheinum; dsectp->floorpal = ssectp->floorpal; dsectp->ceilingpal = ssectp->ceilingpal; dsectp->floorxpan_ = ssectp->floorxpan_; dsectp->ceilingxpan_ = ssectp->ceilingxpan_; dsectp->floorypan_ = ssectp->floorypan_; dsectp->ceilingypan_ = ssectp->ceilingypan_; dsectp->floorstat = ssectp->floorstat; dsectp->ceilingstat = ssectp->ceilingstat; dsectp->extra = ssectp->extra; dsectp->visibility = ssectp->visibility; if (ssectp->floorpicnum == FAF_MIRROR_PIC || ssectp->ceilingpicnum == FAF_MIRROR_PIC) { CollectPortals(); // unavoidable. Since these portals are not static we have to reinitialize all of them. } } } } // do this outside of processing loop for safety // kill all matching dest it.Reset(STAT_COPY_DEST); while (auto dActor = it.Next()) { if (match == dActor->s().lotag) KillActor(dActor); } // kill all matching sources it.Reset(STAT_COPY_SOURCE); while (auto sActor = it.Next()) { if (match == sActor->s().lotag) KillActor(sActor); } } END_SW_NS