DEADSOFTWARE

manager: remove flag 0x8000 from resource handle id
[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 "files.h"
32 #include "game.h"
33 #include "my.h"
34 #include "monster.h"
36 #define MAXSW 100
38 typedef struct {
39 byte x, y;
40 byte t, tm;
41 byte a, b, c, d;
42 byte f;
43 } sw_t;
45 int sw_secrets;
47 static sw_t sw[MAXSW];
48 static void *sndswn, *sndswx, *sndnoway, *sndbdo, *sndbdc, *sndnotele;
49 static int swsnd;
50 static byte cht, chto, chf, f_ch;
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 n = myfread32(h);
76 for (i = 0; i < n; i++) {
77 sw[i].x = myfread8(h);
78 sw[i].y = myfread8(h);
79 sw[i].t = myfread8(h);
80 sw[i].tm = myfread8(h);
81 sw[i].a = myfread8(h);
82 sw[i].b = myfread8(h);
83 sw[i].c = myfread8(h);
84 sw[i].d = myfread8(h);
85 sw[i].f = myfread8(h);
86 }
87 sw_secrets = myfread32(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 sw[i].x = myfread8(h);
97 sw[i].y = myfread8(h);
98 sw[i].t = myfread8(h);
99 sw[i].tm = myfread8(h); // unused
100 sw[i].a = myfread8(h);
101 sw[i].b = myfread8(h);
102 sw[i].c = myfread8(h);
103 sw[i].d = myfread8(h); // unused
104 sw[i].f = myfread8(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;
128 for (i = 0; i < MAXSW; i++) {
129 sw[i].t = 0;
131 swsnd = 0;
134 static void door(byte x,byte y) {
135 byte ex;
137 if(x>=FLDW || y>=FLDH) return;
138 if(fld[y][x]!=cht) return;
139 ex=x+1;
140 for(;x && fld[y][x-1]==cht;--x);
141 for(;ex<FLDW && fld[y][ex]==cht;++ex);
142 memset(fld[y]+x,chto,ex-x);
143 if(f_ch) memset(fldf[y]+x,chf,ex-x);
144 for(;x<ex;++x) {
145 door(x,y-1);
146 door(x,y+1);
150 void Z_water_trap (obj_t *o) {
151 int i,j,sx,sy,x,y;
153 if((y=o->y)>=FLDH*CELH+o->h) return;
154 if((x=o->x)<0 || o->x>FLDW*CELW) return;
155 sx=(x-o->r)/CELW;
156 sy=(y-o->h+1)/CELH;
157 x=(x+o->r)/CELW;
158 y=(y-o->h/2)/CELH;
159 for(i=sx;i<=x;++i)
160 for(j=sy;j<=y;++j)
161 if(fld[j][i]==5) {
162 cht=5;chto=255;f_ch=0;
163 door(i,j);
167 void Z_untrap (byte t) {
168 byte *p;
169 word n;
171 for(p=(byte*)fld,n=FLDW*FLDH;n;--n,++p)
172 if(*p==255) *p=t;
175 static void opendoor(int i) {
176 int j;
178 swsnd=Z_sound(sndbdo,128);
179 j=fldf[sw[i].b][sw[i].a];
180 cht=2;chto=3;chf=0;f_ch=1;
181 door(sw[i].a,sw[i].b);
182 fldf[sw[i].b][sw[i].a]=j;
183 fld_need_remap=1;
186 static int shutdoor(int i) {
187 int j;
189 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
190 door(sw[i].a,sw[i].b);
191 cht=255;
192 if(Z_chktrap(0,0,-3,HIT_SOME)) {
193 j=fldf[sw[i].b][sw[i].a];
194 chto=3;chf=0;f_ch=1;
195 door(sw[i].a,sw[i].b);
196 fldf[sw[i].b][sw[i].a]=j;
197 return 0;
199 chto=2;
200 door(sw[i].a,sw[i].b);
201 fld_need_remap=1;
202 swsnd=Z_sound(sndbdc,128);
203 return 1;
206 void SW_act (void) {
207 int i;
209 if(swsnd) --swsnd;
210 for(i=0;i<MAXSW;++i) if(sw[i].t) {
211 if(sw[i].tm) --sw[i].tm;
212 switch(sw[i].t) {
213 case SW_DOOR5: case SW_DOOR: case SW_SHUTDOOR:
214 if(!sw[i].d) break;
215 if(fld[sw[i].b][sw[i].a]!=3) {sw[i].d=0;break;}
216 if(--sw[i].d==0) if(!shutdoor(i)) sw[i].d=9;
217 break;
218 case SW_TRAP:
219 if(!sw[i].d) break;
220 if(fld[sw[i].b][sw[i].a]!=2) {sw[i].d=0;break;}
221 if(--sw[i].d==0) {opendoor(i);sw[i].tm=18;}
222 break;
227 static int doortime(int t) {
228 switch(t) {
229 case SW_DOOR5: return 90;
231 return 0;
234 void SW_cheat_open (void) {
235 int i;
237 for(i=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) switch(sw[i].t) {
238 case SW_DOOR: case SW_DOOR5:
239 case SW_OPENDOOR:
240 if(fld[sw[i].b][sw[i].a]!=2) break;
241 SW_press(sw[i].x*CELW+4,sw[i].y*CELH+4,1,1,0xFF,-3);
242 break;
246 int SW_press (int x, int y, int r, int h, byte t, int o) {
247 int sx,sy,i,p;
249 sx=(x-r)/CELW;sy=(y-h+1)/CELH;
250 x=(x+r)/CELW;y/=CELH;
251 for(i=p=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) {
252 if(sw[i].x>=sx && sw[i].x<=x && sw[i].y>=sy && sw[i].y<=y && ((sw[i].f&0x8F)&t)) {
253 if(sw[i].f&0x70) if((sw[i].f&(t&0x70))!=(sw[i].f&0x70)) continue;
254 switch(sw[i].t) {
255 case SW_EXIT:
256 g_exit=1;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
257 case SW_EXITS:
258 g_exit=2;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
259 case SW_DOOR: case SW_DOOR5:
260 switch(fld[sw[i].b][sw[i].a]) {
261 case 2:
262 opendoor(i);sw[i].tm=9;sw[i].d=doortime(sw[i].t);break;
263 case 3:
264 if(shutdoor(i)) {sw[i].tm=9;sw[i].d=0;}
265 else {
266 if(!swsnd) swsnd=Z_sound(sndnoway,128);
267 sw[i].d=2;
268 }break;
269 }break;
270 case SW_PRESS:
271 sw[i].tm=9;
272 SW_press((dword)sw[i].a*8+4,(dword)sw[i].b*8+12,8,16,(t&0x70)|0x80,o);
273 break;
274 case SW_TELE:
275 if(o < -2) break;
276 if(!Z_canfit((dword)sw[i].a*8+4,(dword)sw[i].b*8+7,r,h)) {
277 if(!swsnd) swsnd=Z_sound(sndnotele,128);
278 break;
279 }Z_teleobj(o,(dword)sw[i].a*8+4,(dword)sw[i].b*8+7);
280 sw[i].tm=1;
281 break;
282 case SW_OPENDOOR:
283 if(fld[sw[i].b][sw[i].a]!=2) break;
284 opendoor(i);
285 sw[i].tm=1;
286 break;
287 case SW_SHUTDOOR:
288 if(fld[sw[i].b][sw[i].a]!=3) break;
289 if(shutdoor(i)) {sw[i].tm=1;sw[i].d=0;}
290 else {
291 if(!swsnd) swsnd=Z_sound(sndnoway,128);
292 sw[i].d=2;
293 }break;
294 case SW_SHUTTRAP: case SW_TRAP:
295 if(fld[sw[i].b][sw[i].a]!=3) break;
296 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
297 door(sw[i].a,sw[i].b);
298 Z_chktrap(1,100,-3,HIT_TRAP);
299 cht=255;chto=2;
300 door(sw[i].a,sw[i].b);
301 fld_need_remap=1;
302 swsnd=Z_sound(sndswn,128);
303 sw[i].tm=1;sw[i].d=20;
304 break;
305 case SW_LIFT:
306 if(fld[sw[i].b][sw[i].a]==10) {
307 cht=10;chto=9;f_ch=0;
308 }else if(fld[sw[i].b][sw[i].a]==9) {
309 cht=9;chto=10;f_ch=0;
310 }else break;
311 door(sw[i].a,sw[i].b);
312 fld_need_remap=1;
313 swsnd=Z_sound(sndswx,128);
314 sw[i].tm=9;
315 break;
316 case SW_LIFTUP:
317 if(fld[sw[i].b][sw[i].a]!=10) break;
318 cht=10;chto=9;f_ch=0;
319 door(sw[i].a,sw[i].b);
320 fld_need_remap=1;
321 swsnd=Z_sound(sndswx,128);
322 sw[i].tm=1;
323 break;
324 case SW_LIFTDOWN:
325 if(fld[sw[i].b][sw[i].a]!=9) break;
326 cht=9;chto=10;f_ch=0;
327 door(sw[i].a,sw[i].b);
328 fld_need_remap=1;
329 swsnd=Z_sound(sndswx,128);
330 sw[i].tm=1;
331 break;
332 case SW_SECRET:
333 if(o!=-1 && o!=-2) break;
334 if(o==-1) ++pl1.secrets;
335 else ++pl2.secrets;
336 sw[i].tm=1;sw[i].t=0;break;
338 if (sw[i].tm != 0) {
339 R_switch_texture(sw[i].x, sw[i].y);
340 p = 1;
342 if(sw[i].tm==1) sw[i].tm=0;
345 return p;