DEADSOFTWARE

980955dee5f54ad7ebb42b5be4c9b00f806fe2b0
[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 n;
55 for(n=MAXSW;--n;) if(sw[n].t) break;
56 ++n;myfwrite(&n,1,4,h);myfwrite(sw,1,n*sizeof(sw[0]),h);
57 myfwrite(&sw_secrets,1,4,h);
58 }
60 void SW_loadgame(FILE* h) {
61 int n;
63 myfread(&n,1,4,h);myfread(sw,1,n*sizeof(sw[0]),h);
64 myfread(&sw_secrets,1,4,h);
65 }
67 int SW_load(FILE* h) {
68 int i;
70 switch(blk.t) {
71 case MB_SWITCH2:
72 sw_secrets=0;
73 for(i=0;i<MAXSW && blk.sz>0;++i,blk.sz-=sizeof(sw_t)) {
74 myfread(sw+i,1,sizeof(sw_t),h);
75 sw[i].c = short2host(sw[i].c);
76 sw[i].tm=0;sw[i].d=0;
77 sw[i].f|=0x80;
78 if(sw[i].t==SW_SECRET) ++sw_secrets;
79 }
80 return 1;
81 }return 0;
82 }
84 void SW_alloc(void) {
85 sndswn=Z_getsnd("SWTCHN");
86 sndswx=Z_getsnd("SWTCHX");
87 sndnoway=Z_getsnd("NOWAY");
88 sndbdo=Z_getsnd("BDOPN");
89 sndbdc=Z_getsnd("BDCLS");
90 sndnotele=Z_getsnd("NOTELE");
91 }
93 void SW_init(void) {
94 int i;
96 for(i=0;i<MAXSW;++i) sw[i].t=0;
97 swsnd=0;
98 }
100 static byte cht,chto,chf,f_ch;
102 static void door(byte x,byte y) {
103 byte ex;
105 if(x>=FLDW || y>=FLDH) return;
106 if(fld[y][x]!=cht) return;
107 ex=x+1;
108 for(;x && fld[y][x-1]==cht;--x);
109 for(;ex<FLDW && fld[y][ex]==cht;++ex);
110 memset(fld[y]+x,chto,ex-x);
111 if(f_ch) memset(fldf[y]+x,chf,ex-x);
112 for(;x<ex;++x) {
113 door(x,y-1);
114 door(x,y+1);
118 void Z_water_trap(obj_t *o) {
119 int i,j,sx,sy,x,y;
121 if((y=o->y)>=FLDH*CELH+o->h) return;
122 if((x=o->x)<0 || o->x>FLDW*CELW) return;
123 sx=(x-o->r)/CELW;
124 sy=(y-o->h+1)/CELH;
125 x=(x+o->r)/CELW;
126 y=(y-o->h/2)/CELH;
127 for(i=sx;i<=x;++i)
128 for(j=sy;j<=y;++j)
129 if(fld[j][i]==5) {
130 cht=5;chto=255;f_ch=0;
131 door(i,j);
135 void Z_untrap(byte t) {
136 byte *p;
137 word n;
139 for(p=(byte*)fld,n=FLDW*FLDH;n;--n,++p)
140 if(*p==255) *p=t;
143 static void opendoor(int i) {
144 int j;
146 swsnd=Z_sound(sndbdo,128);
147 j=fldf[sw[i].b][sw[i].a];
148 cht=2;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 fld_need_remap=1;
154 static int shutdoor(int i) {
155 int j;
157 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
158 door(sw[i].a,sw[i].b);
159 cht=255;
160 if(Z_chktrap(0,0,-3,HIT_SOME)) {
161 j=fldf[sw[i].b][sw[i].a];
162 chto=3;chf=0;f_ch=1;
163 door(sw[i].a,sw[i].b);
164 fldf[sw[i].b][sw[i].a]=j;
165 return 0;
167 chto=2;
168 door(sw[i].a,sw[i].b);
169 fld_need_remap=1;
170 swsnd=Z_sound(sndbdc,128);
171 return 1;
174 void SW_act(void) {
175 int i;
177 if(swsnd) --swsnd;
178 for(i=0;i<MAXSW;++i) if(sw[i].t) {
179 if(sw[i].tm) --sw[i].tm;
180 switch(sw[i].t) {
181 case SW_DOOR5: case SW_DOOR: case SW_SHUTDOOR:
182 if(!sw[i].d) break;
183 if(fld[sw[i].b][sw[i].a]!=3) {sw[i].d=0;break;}
184 if(--sw[i].d==0) if(!shutdoor(i)) sw[i].d=9;
185 break;
186 case SW_TRAP:
187 if(!sw[i].d) break;
188 if(fld[sw[i].b][sw[i].a]!=2) {sw[i].d=0;break;}
189 if(--sw[i].d==0) {opendoor(i);sw[i].tm=18;}
190 break;
195 static int doortime(int t) {
196 switch(t) {
197 case SW_DOOR5: return 90;
199 return 0;
202 void SW_cheat_open(void) {
203 int i;
205 for(i=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) switch(sw[i].t) {
206 case SW_DOOR: case SW_DOOR5:
207 case SW_OPENDOOR:
208 if(fld[sw[i].b][sw[i].a]!=2) break;
209 SW_press(sw[i].x*CELW+4,sw[i].y*CELH+4,1,1,0xFF,-3);
210 break;
214 int SW_press(int x,int y,int r,int h,byte t,int o) {
215 int sx,sy,i,p;
217 sx=(x-r)/CELW;sy=(y-h+1)/CELH;
218 x=(x+r)/CELW;y/=CELH;
219 for(i=p=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) {
220 if(sw[i].x>=sx && sw[i].x<=x && sw[i].y>=sy && sw[i].y<=y && ((sw[i].f&0x8F)&t)) {
221 if(sw[i].f&0x70) if((sw[i].f&(t&0x70))!=(sw[i].f&0x70)) continue;
222 switch(sw[i].t) {
223 case SW_EXIT:
224 g_exit=1;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
225 case SW_EXITS:
226 g_exit=2;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
227 case SW_DOOR: case SW_DOOR5:
228 switch(fld[sw[i].b][sw[i].a]) {
229 case 2:
230 opendoor(i);sw[i].tm=9;sw[i].d=doortime(sw[i].t);break;
231 case 3:
232 if(shutdoor(i)) {sw[i].tm=9;sw[i].d=0;}
233 else {
234 if(!swsnd) swsnd=Z_sound(sndnoway,128);
235 sw[i].d=2;
236 }break;
237 }break;
238 case SW_PRESS:
239 sw[i].tm=9;
240 SW_press((dword)sw[i].a*8+4,(dword)sw[i].b*8+12,8,16,(t&0x70)|0x80,o);
241 break;
242 case SW_TELE:
243 if(o < -2) break;
244 if(!Z_canfit((dword)sw[i].a*8+4,(dword)sw[i].b*8+7,r,h)) {
245 if(!swsnd) swsnd=Z_sound(sndnotele,128);
246 break;
247 }Z_teleobj(o,(dword)sw[i].a*8+4,(dword)sw[i].b*8+7);
248 sw[i].tm=1;
249 break;
250 case SW_OPENDOOR:
251 if(fld[sw[i].b][sw[i].a]!=2) break;
252 opendoor(i);
253 sw[i].tm=1;
254 break;
255 case SW_SHUTDOOR:
256 if(fld[sw[i].b][sw[i].a]!=3) break;
257 if(shutdoor(i)) {sw[i].tm=1;sw[i].d=0;}
258 else {
259 if(!swsnd) swsnd=Z_sound(sndnoway,128);
260 sw[i].d=2;
261 }break;
262 case SW_SHUTTRAP: case SW_TRAP:
263 if(fld[sw[i].b][sw[i].a]!=3) break;
264 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
265 door(sw[i].a,sw[i].b);
266 Z_chktrap(1,100,-3,HIT_TRAP);
267 cht=255;chto=2;
268 door(sw[i].a,sw[i].b);
269 fld_need_remap=1;
270 swsnd=Z_sound(sndswn,128);
271 sw[i].tm=1;sw[i].d=20;
272 break;
273 case SW_LIFT:
274 if(fld[sw[i].b][sw[i].a]==10) {
275 cht=10;chto=9;f_ch=0;
276 }else if(fld[sw[i].b][sw[i].a]==9) {
277 cht=9;chto=10;f_ch=0;
278 }else break;
279 door(sw[i].a,sw[i].b);
280 fld_need_remap=1;
281 swsnd=Z_sound(sndswx,128);
282 sw[i].tm=9;
283 break;
284 case SW_LIFTUP:
285 if(fld[sw[i].b][sw[i].a]!=10) break;
286 cht=10;chto=9;f_ch=0;
287 door(sw[i].a,sw[i].b);
288 fld_need_remap=1;
289 swsnd=Z_sound(sndswx,128);
290 sw[i].tm=1;
291 break;
292 case SW_LIFTDOWN:
293 if(fld[sw[i].b][sw[i].a]!=9) break;
294 cht=9;chto=10;f_ch=0;
295 door(sw[i].a,sw[i].b);
296 fld_need_remap=1;
297 swsnd=Z_sound(sndswx,128);
298 sw[i].tm=1;
299 break;
300 case SW_SECRET:
301 if(o!=-1 && o!=-2) break;
302 if(o==-1) ++pl1.secrets;
303 else ++pl2.secrets;
304 sw[i].tm=1;sw[i].t=0;break;
306 if(sw[i].tm)
307 {fldb[sw[i].y][sw[i].x]=walswp[fldb[sw[i].y][sw[i].x]];p=1;}
308 if(sw[i].tm==1) sw[i].tm=0;
311 return p;