DEADSOFTWARE

save: move save code to separated file
[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"
35 #include "render.h"
37 int sw_secrets;
38 sw_t sw[MAXSW];
40 static void *sndswn, *sndswx, *sndnoway, *sndbdo, *sndbdc, *sndnotele;
41 static int swsnd;
42 static byte cht, chto, chf, f_ch;
44 int SW_load (FILE *h) {
45 int i;
46 switch(blk.t) {
47 case MB_SWITCH2:
48 sw_secrets = 0;
49 for (i = 0; i < MAXSW && blk.sz > 0; ++i, blk.sz -= 9) {
50 sw[i].x = myfread8(h);
51 sw[i].y = myfread8(h);
52 sw[i].t = myfread8(h);
53 sw[i].tm = myfread8(h); // unused
54 sw[i].a = myfread8(h);
55 sw[i].b = myfread8(h);
56 sw[i].c = myfread8(h);
57 sw[i].d = myfread8(h); // unused
58 sw[i].f = myfread8(h);
59 sw[i].tm = 0;
60 sw[i].d = 0;
61 sw[i].f |= 0x80;
62 if (sw[i].t == SW_SECRET) {
63 ++sw_secrets;
64 }
65 }
66 return 1;
67 }
68 return 0;
69 }
71 void SW_alloc (void) {
72 sndswn=Z_getsnd("SWTCHN");
73 sndswx=Z_getsnd("SWTCHX");
74 sndnoway=Z_getsnd("NOWAY");
75 sndbdo=Z_getsnd("BDOPN");
76 sndbdc=Z_getsnd("BDCLS");
77 sndnotele=Z_getsnd("NOTELE");
78 }
80 void SW_init (void) {
81 int i;
82 for (i = 0; i < MAXSW; i++) {
83 sw[i].t = 0;
84 }
85 swsnd = 0;
86 }
88 static void door(byte x,byte y) {
89 byte ex;
91 if(x>=FLDW || y>=FLDH) return;
92 if(fld[y][x]!=cht) return;
93 ex=x+1;
94 for(;x && fld[y][x-1]==cht;--x);
95 for(;ex<FLDW && fld[y][ex]==cht;++ex);
96 memset(fld[y]+x,chto,ex-x);
97 if(f_ch) memset(fldf[y]+x,chf,ex-x);
98 for(;x<ex;++x) {
99 door(x,y-1);
100 door(x,y+1);
104 void Z_water_trap (obj_t *o) {
105 int i,j,sx,sy,x,y;
107 if((y=o->y)>=FLDH*CELH+o->h) return;
108 if((x=o->x)<0 || o->x>FLDW*CELW) return;
109 sx=(x-o->r)/CELW;
110 sy=(y-o->h+1)/CELH;
111 x=(x+o->r)/CELW;
112 y=(y-o->h/2)/CELH;
113 for(i=sx;i<=x;++i)
114 for(j=sy;j<=y;++j)
115 if(fld[j][i]==5) {
116 cht=5;chto=255;f_ch=0;
117 door(i,j);
121 void Z_untrap (byte t) {
122 byte *p;
123 word n;
125 for(p=(byte*)fld,n=FLDW*FLDH;n;--n,++p)
126 if(*p==255) *p=t;
129 static void opendoor(int i) {
130 int j;
132 swsnd=Z_sound(sndbdo,128);
133 j=fldf[sw[i].b][sw[i].a];
134 cht=2;chto=3;chf=0;f_ch=1;
135 door(sw[i].a,sw[i].b);
136 fldf[sw[i].b][sw[i].a]=j;
137 fld_need_remap=1;
140 static int shutdoor(int i) {
141 int j;
143 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
144 door(sw[i].a,sw[i].b);
145 cht=255;
146 if(Z_chktrap(0,0,-3,HIT_SOME)) {
147 j=fldf[sw[i].b][sw[i].a];
148 chto=3;chf=0;f_ch=1;
149 door(sw[i].a,sw[i].b);
150 fldf[sw[i].b][sw[i].a]=j;
151 return 0;
153 chto=2;
154 door(sw[i].a,sw[i].b);
155 fld_need_remap=1;
156 swsnd=Z_sound(sndbdc,128);
157 return 1;
160 void SW_act (void) {
161 int i;
163 if(swsnd) --swsnd;
164 for(i=0;i<MAXSW;++i) if(sw[i].t) {
165 if(sw[i].tm) --sw[i].tm;
166 switch(sw[i].t) {
167 case SW_DOOR5: case SW_DOOR: case SW_SHUTDOOR:
168 if(!sw[i].d) break;
169 if(fld[sw[i].b][sw[i].a]!=3) {sw[i].d=0;break;}
170 if(--sw[i].d==0) if(!shutdoor(i)) sw[i].d=9;
171 break;
172 case SW_TRAP:
173 if(!sw[i].d) break;
174 if(fld[sw[i].b][sw[i].a]!=2) {sw[i].d=0;break;}
175 if(--sw[i].d==0) {opendoor(i);sw[i].tm=18;}
176 break;
181 static int doortime(int t) {
182 switch(t) {
183 case SW_DOOR5: return 90;
185 return 0;
188 void SW_cheat_open (void) {
189 int i;
191 for(i=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) switch(sw[i].t) {
192 case SW_DOOR: case SW_DOOR5:
193 case SW_OPENDOOR:
194 if(fld[sw[i].b][sw[i].a]!=2) break;
195 SW_press(sw[i].x*CELW+4,sw[i].y*CELH+4,1,1,0xFF,-3);
196 break;
200 int SW_press (int x, int y, int r, int h, byte t, int o) {
201 int sx,sy,i,p;
203 sx=(x-r)/CELW;sy=(y-h+1)/CELH;
204 x=(x+r)/CELW;y/=CELH;
205 for(i=p=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) {
206 if(sw[i].x>=sx && sw[i].x<=x && sw[i].y>=sy && sw[i].y<=y && ((sw[i].f&0x8F)&t)) {
207 if(sw[i].f&0x70) if((sw[i].f&(t&0x70))!=(sw[i].f&0x70)) continue;
208 switch(sw[i].t) {
209 case SW_EXIT:
210 g_exit=1;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
211 case SW_EXITS:
212 g_exit=2;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
213 case SW_DOOR: case SW_DOOR5:
214 switch(fld[sw[i].b][sw[i].a]) {
215 case 2:
216 opendoor(i);sw[i].tm=9;sw[i].d=doortime(sw[i].t);break;
217 case 3:
218 if(shutdoor(i)) {sw[i].tm=9;sw[i].d=0;}
219 else {
220 if(!swsnd) swsnd=Z_sound(sndnoway,128);
221 sw[i].d=2;
222 }break;
223 }break;
224 case SW_PRESS:
225 sw[i].tm=9;
226 SW_press((dword)sw[i].a*8+4,(dword)sw[i].b*8+12,8,16,(t&0x70)|0x80,o);
227 break;
228 case SW_TELE:
229 if(o < -2) break;
230 if(!Z_canfit((dword)sw[i].a*8+4,(dword)sw[i].b*8+7,r,h)) {
231 if(!swsnd) swsnd=Z_sound(sndnotele,128);
232 break;
233 }Z_teleobj(o,(dword)sw[i].a*8+4,(dword)sw[i].b*8+7);
234 sw[i].tm=1;
235 break;
236 case SW_OPENDOOR:
237 if(fld[sw[i].b][sw[i].a]!=2) break;
238 opendoor(i);
239 sw[i].tm=1;
240 break;
241 case SW_SHUTDOOR:
242 if(fld[sw[i].b][sw[i].a]!=3) break;
243 if(shutdoor(i)) {sw[i].tm=1;sw[i].d=0;}
244 else {
245 if(!swsnd) swsnd=Z_sound(sndnoway,128);
246 sw[i].d=2;
247 }break;
248 case SW_SHUTTRAP: case SW_TRAP:
249 if(fld[sw[i].b][sw[i].a]!=3) break;
250 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
251 door(sw[i].a,sw[i].b);
252 Z_chktrap(1,100,-3,HIT_TRAP);
253 cht=255;chto=2;
254 door(sw[i].a,sw[i].b);
255 fld_need_remap=1;
256 swsnd=Z_sound(sndswn,128);
257 sw[i].tm=1;sw[i].d=20;
258 break;
259 case SW_LIFT:
260 if(fld[sw[i].b][sw[i].a]==10) {
261 cht=10;chto=9;f_ch=0;
262 }else if(fld[sw[i].b][sw[i].a]==9) {
263 cht=9;chto=10;f_ch=0;
264 }else break;
265 door(sw[i].a,sw[i].b);
266 fld_need_remap=1;
267 swsnd=Z_sound(sndswx,128);
268 sw[i].tm=9;
269 break;
270 case SW_LIFTUP:
271 if(fld[sw[i].b][sw[i].a]!=10) break;
272 cht=10;chto=9;f_ch=0;
273 door(sw[i].a,sw[i].b);
274 fld_need_remap=1;
275 swsnd=Z_sound(sndswx,128);
276 sw[i].tm=1;
277 break;
278 case SW_LIFTDOWN:
279 if(fld[sw[i].b][sw[i].a]!=9) break;
280 cht=9;chto=10;f_ch=0;
281 door(sw[i].a,sw[i].b);
282 fld_need_remap=1;
283 swsnd=Z_sound(sndswx,128);
284 sw[i].tm=1;
285 break;
286 case SW_SECRET:
287 if(o!=-1 && o!=-2) break;
288 if(o==-1) ++pl1.secrets;
289 else ++pl2.secrets;
290 sw[i].tm=1;sw[i].t=0;break;
292 if (sw[i].tm != 0) {
293 R_switch_texture(sw[i].x, sw[i].y);
294 p = 1;
296 if(sw[i].tm==1) sw[i].tm=0;
299 return p;