1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 1997, 2005 - 3D Realms Entertainment
4
5 This file is part of Shadow Warrior version 1.2
6
7 Shadow Warrior is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 Original Source: 1997 - Frank Maddin and Jim Norwood
23 Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
24 */
25 //-------------------------------------------------------------------------
26 #include "build.h"
27
28 #include "names2.h"
29 #include "game.h"
30 #include "tags.h"
31 #include "weapon.h"
32 #include "sprite.h"
33 #include "track.h"
34
CopySectorWalls(short dest_sectnum,short src_sectnum)35 void CopySectorWalls(short dest_sectnum, short src_sectnum)
36 {
37 short dest_wall_num, src_wall_num, start_wall;
38
39 dest_wall_num = sector[dest_sectnum].wallptr;
40 src_wall_num = sector[src_sectnum].wallptr;
41
42 start_wall = dest_wall_num;
43
44 do
45 {
46 wall[dest_wall_num].picnum = wall[src_wall_num].picnum;
47
48 wall[dest_wall_num].xrepeat = wall[src_wall_num].xrepeat;
49 wall[dest_wall_num].yrepeat = wall[src_wall_num].yrepeat;
50 wall[dest_wall_num].overpicnum = wall[src_wall_num].overpicnum;
51 wall[dest_wall_num].pal = wall[src_wall_num].pal;
52 wall[dest_wall_num].cstat = wall[src_wall_num].cstat;
53 wall[dest_wall_num].shade = wall[src_wall_num].shade;
54 wall[dest_wall_num].xpanning = wall[src_wall_num].xpanning;
55 wall[dest_wall_num].ypanning = wall[src_wall_num].ypanning;
56 wall[dest_wall_num].hitag = wall[src_wall_num].hitag;
57 wall[dest_wall_num].lotag = wall[src_wall_num].lotag;
58 wall[dest_wall_num].extra = wall[src_wall_num].extra;
59
60 if (wall[dest_wall_num].nextwall >= 0 && wall[src_wall_num].nextwall >= 0)
61 {
62 wall[wall[dest_wall_num].nextwall].picnum = wall[wall[src_wall_num].nextwall].picnum;
63 wall[wall[dest_wall_num].nextwall].xrepeat = wall[wall[src_wall_num].nextwall].xrepeat;
64 wall[wall[dest_wall_num].nextwall].yrepeat = wall[wall[src_wall_num].nextwall].yrepeat;
65 wall[wall[dest_wall_num].nextwall].overpicnum = wall[wall[src_wall_num].nextwall].overpicnum;
66 wall[wall[dest_wall_num].nextwall].pal = wall[wall[src_wall_num].nextwall].pal;
67 wall[wall[dest_wall_num].nextwall].cstat = wall[wall[src_wall_num].nextwall].cstat;
68 wall[wall[dest_wall_num].nextwall].shade = wall[wall[src_wall_num].nextwall].shade;
69 wall[wall[dest_wall_num].nextwall].xpanning = wall[wall[src_wall_num].nextwall].xpanning;
70 wall[wall[dest_wall_num].nextwall].ypanning = wall[wall[src_wall_num].nextwall].ypanning;
71 wall[wall[dest_wall_num].nextwall].hitag = wall[wall[src_wall_num].nextwall].hitag;
72 wall[wall[dest_wall_num].nextwall].lotag = wall[wall[src_wall_num].nextwall].lotag;
73 wall[wall[dest_wall_num].nextwall].extra = wall[wall[src_wall_num].nextwall].extra;
74 }
75
76 dest_wall_num = wall[dest_wall_num].point2;
77 src_wall_num = wall[src_wall_num].point2;
78 }
79 while(dest_wall_num != start_wall);
80 }
81
CopySectorMatch(short match)82 void CopySectorMatch(short match)
83 {
84 short ed,nexted,ss,nextss;
85 SPRITEp dest_sp, src_sp;
86 SECTORp dsectp,ssectp;
87 short kill, nextkill;
88 SPRITEp k;
89
90 TRAVERSE_SPRITE_STAT(headspritestat[STAT_COPY_DEST], ed, nexted)
91 {
92 dest_sp = &sprite[ed];
93 dsectp = §or[dest_sp->sectnum];
94
95 if (match != sprite[ed].lotag)
96 continue;
97
98 TRAVERSE_SPRITE_STAT(headspritestat[STAT_COPY_SOURCE], ss, nextss)
99 {
100 src_sp = &sprite[ss];
101
102 if (SP_TAG2(src_sp) == SPRITE_TAG2(ed) &&
103 SP_TAG3(src_sp) == SPRITE_TAG3(ed))
104 {
105 short src_move, nextsrc_move;
106 ssectp = §or[src_sp->sectnum];
107
108 // !!!!!AAAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHHHHHHH
109 // Don't kill anything you don't have to
110 // this wall killing things on a Queue causing
111 // invalid situations
112
113 #if 1
114 // kill all sprites in the dest sector that need to be
115 TRAVERSE_SPRITE_SECT(headspritesect[dest_sp->sectnum], kill, nextkill)
116 {
117 k = &sprite[kill];
118
119 // kill anything not invisible
120 if (!TEST(k->cstat, CSTAT_SPRITE_INVISIBLE))
121 {
122 if (User[kill])
123 {
124 // be safe with the killing
125 //SetSuicide(kill);
126 }
127 else
128 {
129 SpriteQueueDelete(kill); // new function to allow killing - hopefully
130 KillSprite(kill);
131 }
132 }
133 }
134 #endif
135
136 CopySectorWalls(dest_sp->sectnum, src_sp->sectnum);
137
138 TRAVERSE_SPRITE_SECT(headspritesect[src_sp->sectnum], src_move, nextsrc_move)
139 {
140 // don't move ST1 Copy Tags
141 if (SPRITE_TAG1(src_move) != SECT_COPY_SOURCE)
142 {
143 int sx,sy,dx,dy,src_xoff,src_yoff,trash;
144
145 // move sprites from source to dest - use center offset
146
147 // get center of src and dest sect
148 SectorMidPoint(src_sp->sectnum, &sx, &sy, &trash);
149 SectorMidPoint(dest_sp->sectnum, &dx, &dy, &trash);
150
151 // get offset
152 src_xoff = sx - sprite[src_move].x;
153 src_yoff = sy - sprite[src_move].y;
154
155 // move sprite to dest sector
156 sprite[src_move].x = dx - src_xoff;
157 sprite[src_move].y = dy - src_yoff;
158
159 // change sector
160 changespritesect(src_move, dest_sp->sectnum);
161
162 // check to see if it moved on to a sector object
163 if (TEST(sector[dest_sp->sectnum].extra, SECTFX_SECTOR_OBJECT))
164 {
165 SECTOR_OBJECTp sop;
166 extern short GlobSpeedSO;
167
168 // find and add sprite to SO
169 sop = DetectSectorObject(§or[sprite[src_move].sectnum]);
170 AddSpriteToSectorObject(src_move, sop);
171
172 // update sprites postions so they aren't in the
173 // wrong place for one frame
174 GlobSpeedSO = 0;
175 RefreshPoints(sop, 0, 0, TRUE);
176 }
177 }
178 }
179
180 // copy sector user if there is one
181 if (SectUser[src_sp->sectnum] || SectUser[dest_sp->sectnum])
182 {
183 SECT_USERp ssectu = GetSectUser(src_sp->sectnum);
184 SECT_USERp dsectu = GetSectUser(dest_sp->sectnum);
185
186 memcpy(dsectu, ssectu, sizeof(SECT_USER));
187 }
188
189 dsectp->hitag = ssectp->hitag;
190 dsectp->lotag = ssectp->lotag;
191
192 dsectp->floorz = ssectp->floorz;
193 dsectp->ceilingz = ssectp->ceilingz;
194
195 dsectp->floorshade = ssectp->floorshade;
196 dsectp->ceilingshade = ssectp->ceilingshade;
197
198 dsectp->floorpicnum = ssectp->floorpicnum;
199 dsectp->ceilingpicnum = ssectp->ceilingpicnum;
200
201 dsectp->floorheinum = ssectp->floorheinum;
202 dsectp->ceilingheinum = ssectp->ceilingheinum;
203
204 dsectp->floorpal = ssectp->floorpal;
205 dsectp->ceilingpal = ssectp->ceilingpal;
206
207 dsectp->floorxpanning = ssectp->floorxpanning;
208 dsectp->ceilingxpanning = ssectp->ceilingxpanning;
209
210 dsectp->floorypanning = ssectp->floorypanning;
211 dsectp->ceilingypanning = ssectp->ceilingypanning;
212
213 dsectp->floorstat = ssectp->floorstat;
214 dsectp->ceilingstat = ssectp->ceilingstat;
215
216 dsectp->extra = ssectp->extra;
217 dsectp->visibility = ssectp->visibility;
218 }
219 }
220 }
221
222 // do this outside of processing loop for safety
223
224 // kill all matching dest
225 TRAVERSE_SPRITE_STAT(headspritestat[STAT_COPY_DEST], ed, nexted)
226 {
227 if (match == sprite[ed].lotag)
228 KillSprite(ed);
229 }
230
231 // kill all matching sources
232 TRAVERSE_SPRITE_STAT(headspritestat[STAT_COPY_SOURCE], ss, nextss)
233 {
234 if (match == sprite[ss].lotag)
235 KillSprite(ss);
236 }
237
238 }
239