DEADSOFTWARE

a04650889c04feace9571f39701ae9ac0a8a1a51
[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"
31 #include "my.h"
33 #define MAXSW 100
35 extern map_block_t blk;
37 #pragma pack(1)
38 typedef struct{
39 byte x,y;
40 byte t,tm;
41 byte a,b,c,d;
42 byte f;
43 }sw_t;
44 #pragma pack()
46 static sw_t sw[MAXSW];
48 static void *sndswn,*sndswx,*sndnoway,*sndbdo,*sndbdc,*sndnotele;
49 static int swsnd;
51 int sw_secrets;
53 void SW_savegame (FILE *h) {
54 int i, n;
55 for (n = MAXSW - 1; n >= 0 && sw[n].t == 0; n--) {
56 // empty
57 }
58 n += 1;
59 myfwrite32(n, h);
60 for (i = 0; i < n; i++) {
61 myfwrite8(sw[i].x, h);
62 myfwrite8(sw[i].y, h);
63 myfwrite8(sw[i].t, h);
64 myfwrite8(sw[i].tm, h);
65 myfwrite8(sw[i].a, h);
66 myfwrite8(sw[i].b, h);
67 myfwrite8(sw[i].c, h);
68 myfwrite8(sw[i].d, h);
69 myfwrite8(sw[i].f, h);
70 }
71 myfwrite32(sw_secrets, h);
72 }
74 void SW_loadgame (FILE *h) {
75 int i, n;
76 n = myfread32(h);
77 for (i = 0; i < n; i++) {
78 sw[i].x = myfread8(h);
79 sw[i].y = myfread8(h);
80 sw[i].t = myfread8(h);
81 sw[i].tm = myfread8(h);
82 sw[i].a = myfread8(h);
83 sw[i].b = myfread8(h);
84 sw[i].c = myfread8(h);
85 sw[i].d = myfread8(h);
86 sw[i].f = myfread8(h);
87 }
88 sw_secrets = myfread32(h);
89 }
91 int SW_load (FILE *h) {
92 int i;
93 switch(blk.t) {
94 case MB_SWITCH2:
95 sw_secrets = 0;
96 for (i = 0; i < MAXSW && blk.sz > 0; ++i, blk.sz -= 9) {
97 sw[i].x = myfread8(h);
98 sw[i].y = myfread8(h);
99 sw[i].t = myfread8(h);
100 sw[i].tm = myfread8(h); // unused
101 sw[i].a = myfread8(h);
102 sw[i].b = myfread8(h);
103 sw[i].c = myfread8(h);
104 sw[i].d = myfread8(h); // unused
105 sw[i].f = myfread8(h);
106 sw[i].tm = 0;
107 sw[i].d = 0;
108 sw[i].f |= 0x80;
109 if (sw[i].t == SW_SECRET) {
110 ++sw_secrets;
113 return 1;
115 return 0;
118 void SW_alloc(void) {
119 sndswn=Z_getsnd("SWTCHN");
120 sndswx=Z_getsnd("SWTCHX");
121 sndnoway=Z_getsnd("NOWAY");
122 sndbdo=Z_getsnd("BDOPN");
123 sndbdc=Z_getsnd("BDCLS");
124 sndnotele=Z_getsnd("NOTELE");
127 void SW_init(void) {
128 int i;
130 for(i=0;i<MAXSW;++i) sw[i].t=0;
131 swsnd=0;
134 static byte cht,chto,chf,f_ch;
136 static void door(byte x,byte y) {
137 byte ex;
139 if(x>=FLDW || y>=FLDH) return;
140 if(fld[y][x]!=cht) return;
141 ex=x+1;
142 for(;x && fld[y][x-1]==cht;--x);
143 for(;ex<FLDW && fld[y][ex]==cht;++ex);
144 memset(fld[y]+x,chto,ex-x);
145 if(f_ch) memset(fldf[y]+x,chf,ex-x);
146 for(;x<ex;++x) {
147 door(x,y-1);
148 door(x,y+1);
152 void Z_water_trap(obj_t *o) {
153 int i,j,sx,sy,x,y;
155 if((y=o->y)>=FLDH*CELH+o->h) return;
156 if((x=o->x)<0 || o->x>FLDW*CELW) return;
157 sx=(x-o->r)/CELW;
158 sy=(y-o->h+1)/CELH;
159 x=(x+o->r)/CELW;
160 y=(y-o->h/2)/CELH;
161 for(i=sx;i<=x;++i)
162 for(j=sy;j<=y;++j)
163 if(fld[j][i]==5) {
164 cht=5;chto=255;f_ch=0;
165 door(i,j);
169 void Z_untrap(byte t) {
170 byte *p;
171 word n;
173 for(p=(byte*)fld,n=FLDW*FLDH;n;--n,++p)
174 if(*p==255) *p=t;
177 static void opendoor(int i) {
178 int j;
180 swsnd=Z_sound(sndbdo,128);
181 j=fldf[sw[i].b][sw[i].a];
182 cht=2;chto=3;chf=0;f_ch=1;
183 door(sw[i].a,sw[i].b);
184 fldf[sw[i].b][sw[i].a]=j;
185 fld_need_remap=1;
188 static int shutdoor(int i) {
189 int j;
191 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
192 door(sw[i].a,sw[i].b);
193 cht=255;
194 if(Z_chktrap(0,0,-3,HIT_SOME)) {
195 j=fldf[sw[i].b][sw[i].a];
196 chto=3;chf=0;f_ch=1;
197 door(sw[i].a,sw[i].b);
198 fldf[sw[i].b][sw[i].a]=j;
199 return 0;
201 chto=2;
202 door(sw[i].a,sw[i].b);
203 fld_need_remap=1;
204 swsnd=Z_sound(sndbdc,128);
205 return 1;
208 void SW_act(void) {
209 int i;
211 if(swsnd) --swsnd;
212 for(i=0;i<MAXSW;++i) if(sw[i].t) {
213 if(sw[i].tm) --sw[i].tm;
214 switch(sw[i].t) {
215 case SW_DOOR5: case SW_DOOR: case SW_SHUTDOOR:
216 if(!sw[i].d) break;
217 if(fld[sw[i].b][sw[i].a]!=3) {sw[i].d=0;break;}
218 if(--sw[i].d==0) if(!shutdoor(i)) sw[i].d=9;
219 break;
220 case SW_TRAP:
221 if(!sw[i].d) break;
222 if(fld[sw[i].b][sw[i].a]!=2) {sw[i].d=0;break;}
223 if(--sw[i].d==0) {opendoor(i);sw[i].tm=18;}
224 break;
229 static int doortime(int t) {
230 switch(t) {
231 case SW_DOOR5: return 90;
233 return 0;
236 void SW_cheat_open(void) {
237 int i;
239 for(i=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) switch(sw[i].t) {
240 case SW_DOOR: case SW_DOOR5:
241 case SW_OPENDOOR:
242 if(fld[sw[i].b][sw[i].a]!=2) break;
243 SW_press(sw[i].x*CELW+4,sw[i].y*CELH+4,1,1,0xFF,-3);
244 break;
248 int SW_press(int x,int y,int r,int h,byte t,int o) {
249 int sx,sy,i,p;
251 sx=(x-r)/CELW;sy=(y-h+1)/CELH;
252 x=(x+r)/CELW;y/=CELH;
253 for(i=p=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) {
254 if(sw[i].x>=sx && sw[i].x<=x && sw[i].y>=sy && sw[i].y<=y && ((sw[i].f&0x8F)&t)) {
255 if(sw[i].f&0x70) if((sw[i].f&(t&0x70))!=(sw[i].f&0x70)) continue;
256 switch(sw[i].t) {
257 case SW_EXIT:
258 g_exit=1;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
259 case SW_EXITS:
260 g_exit=2;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
261 case SW_DOOR: case SW_DOOR5:
262 switch(fld[sw[i].b][sw[i].a]) {
263 case 2:
264 opendoor(i);sw[i].tm=9;sw[i].d=doortime(sw[i].t);break;
265 case 3:
266 if(shutdoor(i)) {sw[i].tm=9;sw[i].d=0;}
267 else {
268 if(!swsnd) swsnd=Z_sound(sndnoway,128);
269 sw[i].d=2;
270 }break;
271 }break;
272 case SW_PRESS:
273 sw[i].tm=9;
274 SW_press((dword)sw[i].a*8+4,(dword)sw[i].b*8+12,8,16,(t&0x70)|0x80,o);
275 break;
276 case SW_TELE:
277 if(o < -2) break;
278 if(!Z_canfit((dword)sw[i].a*8+4,(dword)sw[i].b*8+7,r,h)) {
279 if(!swsnd) swsnd=Z_sound(sndnotele,128);
280 break;
281 }Z_teleobj(o,(dword)sw[i].a*8+4,(dword)sw[i].b*8+7);
282 sw[i].tm=1;
283 break;
284 case SW_OPENDOOR:
285 if(fld[sw[i].b][sw[i].a]!=2) break;
286 opendoor(i);
287 sw[i].tm=1;
288 break;
289 case SW_SHUTDOOR:
290 if(fld[sw[i].b][sw[i].a]!=3) break;
291 if(shutdoor(i)) {sw[i].tm=1;sw[i].d=0;}
292 else {
293 if(!swsnd) swsnd=Z_sound(sndnoway,128);
294 sw[i].d=2;
295 }break;
296 case SW_SHUTTRAP: case SW_TRAP:
297 if(fld[sw[i].b][sw[i].a]!=3) break;
298 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
299 door(sw[i].a,sw[i].b);
300 Z_chktrap(1,100,-3,HIT_TRAP);
301 cht=255;chto=2;
302 door(sw[i].a,sw[i].b);
303 fld_need_remap=1;
304 swsnd=Z_sound(sndswn,128);
305 sw[i].tm=1;sw[i].d=20;
306 break;
307 case SW_LIFT:
308 if(fld[sw[i].b][sw[i].a]==10) {
309 cht=10;chto=9;f_ch=0;
310 }else if(fld[sw[i].b][sw[i].a]==9) {
311 cht=9;chto=10;f_ch=0;
312 }else break;
313 door(sw[i].a,sw[i].b);
314 fld_need_remap=1;
315 swsnd=Z_sound(sndswx,128);
316 sw[i].tm=9;
317 break;
318 case SW_LIFTUP:
319 if(fld[sw[i].b][sw[i].a]!=10) break;
320 cht=10;chto=9;f_ch=0;
321 door(sw[i].a,sw[i].b);
322 fld_need_remap=1;
323 swsnd=Z_sound(sndswx,128);
324 sw[i].tm=1;
325 break;
326 case SW_LIFTDOWN:
327 if(fld[sw[i].b][sw[i].a]!=9) break;
328 cht=9;chto=10;f_ch=0;
329 door(sw[i].a,sw[i].b);
330 fld_need_remap=1;
331 swsnd=Z_sound(sndswx,128);
332 sw[i].tm=1;
333 break;
334 case SW_SECRET:
335 if(o!=-1 && o!=-2) break;
336 if(o==-1) ++pl1.secrets;
337 else ++pl2.secrets;
338 sw[i].tm=1;sw[i].t=0;break;
340 if(sw[i].tm)
341 {fldb[sw[i].y][sw[i].x]=walswp[fldb[sw[i].y][sw[i].x]];p=1;}
342 if(sw[i].tm==1) sw[i].tm=0;
345 return p;