DEADSOFTWARE

275aed721c9c13437bd38955260f5c70093e3863
[flatwaifu.git] / src / switch.c
1 /*
2 Copyright (C) Prikol Software 1996-1997
3 Copyright (C) Aleksey Volynskov 1996-1997
4 Copyright (C) <ARembo@gmail.com> 2011
6 This file is part of the Doom2D:Rembo project.
8 Doom2D:Rembo is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as
10 published by the Free Software Foundation.
12 Doom2D:Rembo 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. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see <http://www.gnu.org/licenses/> or
19 write to the Free Software Foundation, Inc.,
20 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
23 #include "glob.h"
24 #include <string.h>
25 #include "view.h"
26 #include "bmap.h"
27 #include "switch.h"
28 #include "player.h"
29 #include "misc.h"
30 #include "map.h"
32 #define MAXSW 100
34 extern map_block_t blk;
36 #pragma pack(1)
37 typedef struct{
38 byte x,y;
39 byte t,tm;
40 byte a,b,c,d;
41 byte f;
42 }sw_t;
43 #pragma pack()
45 static sw_t sw[MAXSW];
47 static void *sndswn,*sndswx,*sndnoway,*sndbdo,*sndbdc,*sndnotele;
48 static int swsnd;
50 int sw_secrets;
52 void SW_savegame (FILE *h) {
53 int i, n;
54 for (n = MAXSW - 1; n >= 0 && sw[n].t == 0; n--) {
55 // empty
56 }
57 n += 1;
58 myfwrite32(n, h);
59 for (i = 0; i < n; i++) {
60 myfwrite8(sw[i].x, h);
61 myfwrite8(sw[i].y, h);
62 myfwrite8(sw[i].t, h);
63 myfwrite8(sw[i].tm, h);
64 myfwrite8(sw[i].a, h);
65 myfwrite8(sw[i].b, h);
66 myfwrite8(sw[i].c, h);
67 myfwrite8(sw[i].d, h);
68 myfwrite8(sw[i].f, h);
69 }
70 myfwrite32(sw_secrets, h);
71 }
73 void SW_loadgame (FILE *h) {
74 int i, n;
75 myfread32(&n, h);
76 for (i = 0; i < n; i++) {
77 myfread8(&sw[i].x, h);
78 myfread8(&sw[i].y, h);
79 myfread8(&sw[i].t, h);
80 myfread8(&sw[i].tm, h);
81 myfread8(&sw[i].a, h);
82 myfread8(&sw[i].b, h);
83 myfread8(&sw[i].c, h);
84 myfread8(&sw[i].d, h);
85 myfread8(&sw[i].f, h);
86 }
87 myfread32(&sw_secrets, h);
88 }
90 int SW_load (FILE *h) {
91 int i;
92 switch(blk.t) {
93 case MB_SWITCH2:
94 sw_secrets = 0;
95 for (i = 0; i < MAXSW && blk.sz > 0; ++i, blk.sz -= 9) {
96 myfread8(&sw[i].x, h);
97 myfread8(&sw[i].y, h);
98 myfread8(&sw[i].t, h);
99 myfread8(&sw[i].tm, h); // unused
100 myfread8(&sw[i].a, h);
101 myfread8(&sw[i].b, h);
102 myfread8(&sw[i].c, h);
103 myfread8(&sw[i].d, h); // unused
104 myfread8(&sw[i].f, h);
105 sw[i].tm = 0;
106 sw[i].d = 0;
107 sw[i].f |= 0x80;
108 if (sw[i].t == SW_SECRET) {
109 ++sw_secrets;
112 return 1;
114 return 0;
117 void SW_alloc(void) {
118 sndswn=Z_getsnd("SWTCHN");
119 sndswx=Z_getsnd("SWTCHX");
120 sndnoway=Z_getsnd("NOWAY");
121 sndbdo=Z_getsnd("BDOPN");
122 sndbdc=Z_getsnd("BDCLS");
123 sndnotele=Z_getsnd("NOTELE");
126 void SW_init(void) {
127 int i;
129 for(i=0;i<MAXSW;++i) sw[i].t=0;
130 swsnd=0;
133 static byte cht,chto,chf,f_ch;
135 static void door(byte x,byte y) {
136 byte ex;
138 if(x>=FLDW || y>=FLDH) return;
139 if(fld[y][x]!=cht) return;
140 ex=x+1;
141 for(;x && fld[y][x-1]==cht;--x);
142 for(;ex<FLDW && fld[y][ex]==cht;++ex);
143 memset(fld[y]+x,chto,ex-x);
144 if(f_ch) memset(fldf[y]+x,chf,ex-x);
145 for(;x<ex;++x) {
146 door(x,y-1);
147 door(x,y+1);
151 void Z_water_trap(obj_t *o) {
152 int i,j,sx,sy,x,y;
154 if((y=o->y)>=FLDH*CELH+o->h) return;
155 if((x=o->x)<0 || o->x>FLDW*CELW) return;
156 sx=(x-o->r)/CELW;
157 sy=(y-o->h+1)/CELH;
158 x=(x+o->r)/CELW;
159 y=(y-o->h/2)/CELH;
160 for(i=sx;i<=x;++i)
161 for(j=sy;j<=y;++j)
162 if(fld[j][i]==5) {
163 cht=5;chto=255;f_ch=0;
164 door(i,j);
168 void Z_untrap(byte t) {
169 byte *p;
170 word n;
172 for(p=(byte*)fld,n=FLDW*FLDH;n;--n,++p)
173 if(*p==255) *p=t;
176 static void opendoor(int i) {
177 int j;
179 swsnd=Z_sound(sndbdo,128);
180 j=fldf[sw[i].b][sw[i].a];
181 cht=2;chto=3;chf=0;f_ch=1;
182 door(sw[i].a,sw[i].b);
183 fldf[sw[i].b][sw[i].a]=j;
184 fld_need_remap=1;
187 static int shutdoor(int i) {
188 int j;
190 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
191 door(sw[i].a,sw[i].b);
192 cht=255;
193 if(Z_chktrap(0,0,-3,HIT_SOME)) {
194 j=fldf[sw[i].b][sw[i].a];
195 chto=3;chf=0;f_ch=1;
196 door(sw[i].a,sw[i].b);
197 fldf[sw[i].b][sw[i].a]=j;
198 return 0;
200 chto=2;
201 door(sw[i].a,sw[i].b);
202 fld_need_remap=1;
203 swsnd=Z_sound(sndbdc,128);
204 return 1;
207 void SW_act(void) {
208 int i;
210 if(swsnd) --swsnd;
211 for(i=0;i<MAXSW;++i) if(sw[i].t) {
212 if(sw[i].tm) --sw[i].tm;
213 switch(sw[i].t) {
214 case SW_DOOR5: case SW_DOOR: case SW_SHUTDOOR:
215 if(!sw[i].d) break;
216 if(fld[sw[i].b][sw[i].a]!=3) {sw[i].d=0;break;}
217 if(--sw[i].d==0) if(!shutdoor(i)) sw[i].d=9;
218 break;
219 case SW_TRAP:
220 if(!sw[i].d) break;
221 if(fld[sw[i].b][sw[i].a]!=2) {sw[i].d=0;break;}
222 if(--sw[i].d==0) {opendoor(i);sw[i].tm=18;}
223 break;
228 static int doortime(int t) {
229 switch(t) {
230 case SW_DOOR5: return 90;
232 return 0;
235 void SW_cheat_open(void) {
236 int i;
238 for(i=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) switch(sw[i].t) {
239 case SW_DOOR: case SW_DOOR5:
240 case SW_OPENDOOR:
241 if(fld[sw[i].b][sw[i].a]!=2) break;
242 SW_press(sw[i].x*CELW+4,sw[i].y*CELH+4,1,1,0xFF,-3);
243 break;
247 int SW_press(int x,int y,int r,int h,byte t,int o) {
248 int sx,sy,i,p;
250 sx=(x-r)/CELW;sy=(y-h+1)/CELH;
251 x=(x+r)/CELW;y/=CELH;
252 for(i=p=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) {
253 if(sw[i].x>=sx && sw[i].x<=x && sw[i].y>=sy && sw[i].y<=y && ((sw[i].f&0x8F)&t)) {
254 if(sw[i].f&0x70) if((sw[i].f&(t&0x70))!=(sw[i].f&0x70)) continue;
255 switch(sw[i].t) {
256 case SW_EXIT:
257 g_exit=1;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
258 case SW_EXITS:
259 g_exit=2;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
260 case SW_DOOR: case SW_DOOR5:
261 switch(fld[sw[i].b][sw[i].a]) {
262 case 2:
263 opendoor(i);sw[i].tm=9;sw[i].d=doortime(sw[i].t);break;
264 case 3:
265 if(shutdoor(i)) {sw[i].tm=9;sw[i].d=0;}
266 else {
267 if(!swsnd) swsnd=Z_sound(sndnoway,128);
268 sw[i].d=2;
269 }break;
270 }break;
271 case SW_PRESS:
272 sw[i].tm=9;
273 SW_press((dword)sw[i].a*8+4,(dword)sw[i].b*8+12,8,16,(t&0x70)|0x80,o);
274 break;
275 case SW_TELE:
276 if(o < -2) break;
277 if(!Z_canfit((dword)sw[i].a*8+4,(dword)sw[i].b*8+7,r,h)) {
278 if(!swsnd) swsnd=Z_sound(sndnotele,128);
279 break;
280 }Z_teleobj(o,(dword)sw[i].a*8+4,(dword)sw[i].b*8+7);
281 sw[i].tm=1;
282 break;
283 case SW_OPENDOOR:
284 if(fld[sw[i].b][sw[i].a]!=2) break;
285 opendoor(i);
286 sw[i].tm=1;
287 break;
288 case SW_SHUTDOOR:
289 if(fld[sw[i].b][sw[i].a]!=3) break;
290 if(shutdoor(i)) {sw[i].tm=1;sw[i].d=0;}
291 else {
292 if(!swsnd) swsnd=Z_sound(sndnoway,128);
293 sw[i].d=2;
294 }break;
295 case SW_SHUTTRAP: case SW_TRAP:
296 if(fld[sw[i].b][sw[i].a]!=3) break;
297 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
298 door(sw[i].a,sw[i].b);
299 Z_chktrap(1,100,-3,HIT_TRAP);
300 cht=255;chto=2;
301 door(sw[i].a,sw[i].b);
302 fld_need_remap=1;
303 swsnd=Z_sound(sndswn,128);
304 sw[i].tm=1;sw[i].d=20;
305 break;
306 case SW_LIFT:
307 if(fld[sw[i].b][sw[i].a]==10) {
308 cht=10;chto=9;f_ch=0;
309 }else if(fld[sw[i].b][sw[i].a]==9) {
310 cht=9;chto=10;f_ch=0;
311 }else break;
312 door(sw[i].a,sw[i].b);
313 fld_need_remap=1;
314 swsnd=Z_sound(sndswx,128);
315 sw[i].tm=9;
316 break;
317 case SW_LIFTUP:
318 if(fld[sw[i].b][sw[i].a]!=10) break;
319 cht=10;chto=9;f_ch=0;
320 door(sw[i].a,sw[i].b);
321 fld_need_remap=1;
322 swsnd=Z_sound(sndswx,128);
323 sw[i].tm=1;
324 break;
325 case SW_LIFTDOWN:
326 if(fld[sw[i].b][sw[i].a]!=9) break;
327 cht=9;chto=10;f_ch=0;
328 door(sw[i].a,sw[i].b);
329 fld_need_remap=1;
330 swsnd=Z_sound(sndswx,128);
331 sw[i].tm=1;
332 break;
333 case SW_SECRET:
334 if(o!=-1 && o!=-2) break;
335 if(o==-1) ++pl1.secrets;
336 else ++pl2.secrets;
337 sw[i].tm=1;sw[i].t=0;break;
339 if(sw[i].tm)
340 {fldb[sw[i].y][sw[i].x]=walswp[fldb[sw[i].y][sw[i].x]];p=1;}
341 if(sw[i].tm==1) sw[i].tm=0;
344 return p;