DEADSOFTWARE

886bee934096b71df73538dbd69580096c898988
[flatwaifu.git] / src / switch.c
1 /* Copyright (C) 1996-1997 Aleksey Volynskov
2 * Copyright (C) 2011 Rambo
3 * Copyright (C) 2020 SovietPony
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
18 #include "glob.h"
19 #include <string.h>
20 #include "view.h"
21 #include "bmap.h"
22 #include "switch.h"
23 #include "player.h"
24 #include "misc.h"
25 #include "map.h"
26 #include "files.h"
27 #include "game.h"
28 #include "my.h"
29 #include "monster.h"
30 #include "render.h"
32 int sw_secrets;
33 sw_t sw[MAXSW];
35 static void *sndswn, *sndswx, *sndnoway, *sndbdo, *sndbdc, *sndnotele;
36 static int swsnd;
37 static byte cht, chto, chf, f_ch;
39 void SW_alloc (void) {
40 sndswn=Z_getsnd("SWTCHN");
41 sndswx=Z_getsnd("SWTCHX");
42 sndnoway=Z_getsnd("NOWAY");
43 sndbdo=Z_getsnd("BDOPN");
44 sndbdc=Z_getsnd("BDCLS");
45 sndnotele=Z_getsnd("NOTELE");
46 }
48 void SW_init (void) {
49 int i;
50 for (i = 0; i < MAXSW; i++) {
51 sw[i].t = 0;
52 }
53 swsnd = 0;
54 }
56 static void door(byte x,byte y) {
57 byte ex;
59 if(x>=FLDW || y>=FLDH) return;
60 if(fld[y][x]!=cht) return;
61 ex=x+1;
62 for(;x && fld[y][x-1]==cht;--x);
63 for(;ex<FLDW && fld[y][ex]==cht;++ex);
64 memset(fld[y]+x,chto,ex-x);
65 if(f_ch) memset(fldf[y]+x,chf,ex-x);
66 for(;x<ex;++x) {
67 door(x,y-1);
68 door(x,y+1);
69 }
70 }
72 void Z_water_trap (obj_t *o) {
73 int i,j,sx,sy,x,y;
75 if((y=o->y)>=FLDH*CELH+o->h) return;
76 if((x=o->x)<0 || o->x>FLDW*CELW) return;
77 sx=(x-o->r)/CELW;
78 sy=(y-o->h+1)/CELH;
79 x=(x+o->r)/CELW;
80 y=(y-o->h/2)/CELH;
81 for(i=sx;i<=x;++i)
82 for(j=sy;j<=y;++j)
83 if(fld[j][i]==5) {
84 cht=5;chto=255;f_ch=0;
85 door(i,j);
86 }
87 }
89 void Z_untrap (byte t) {
90 byte *p;
91 word n;
93 for(p=(byte*)fld,n=FLDW*FLDH;n;--n,++p)
94 if(*p==255) *p=t;
95 }
97 static void opendoor(int i) {
98 int j;
100 swsnd=Z_sound(sndbdo,128);
101 j=fldf[sw[i].b][sw[i].a];
102 cht=2;chto=3;chf=0;f_ch=1;
103 door(sw[i].a,sw[i].b);
104 fldf[sw[i].b][sw[i].a]=j;
105 fld_need_remap=1;
108 static int shutdoor(int i) {
109 int j;
111 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
112 door(sw[i].a,sw[i].b);
113 cht=255;
114 if(Z_chktrap(0,0,-3,HIT_SOME)) {
115 j=fldf[sw[i].b][sw[i].a];
116 chto=3;chf=0;f_ch=1;
117 door(sw[i].a,sw[i].b);
118 fldf[sw[i].b][sw[i].a]=j;
119 return 0;
121 chto=2;
122 door(sw[i].a,sw[i].b);
123 fld_need_remap=1;
124 swsnd=Z_sound(sndbdc,128);
125 return 1;
128 void SW_act (void) {
129 int i;
131 if(swsnd) --swsnd;
132 for(i=0;i<MAXSW;++i) if(sw[i].t) {
133 if(sw[i].tm) --sw[i].tm;
134 switch(sw[i].t) {
135 case SW_DOOR5: case SW_DOOR: case SW_SHUTDOOR:
136 if(!sw[i].d) break;
137 if(fld[sw[i].b][sw[i].a]!=3) {sw[i].d=0;break;}
138 if(--sw[i].d==0) if(!shutdoor(i)) sw[i].d=9;
139 break;
140 case SW_TRAP:
141 if(!sw[i].d) break;
142 if(fld[sw[i].b][sw[i].a]!=2) {sw[i].d=0;break;}
143 if(--sw[i].d==0) {opendoor(i);sw[i].tm=18;}
144 break;
149 static int doortime(int t) {
150 switch(t) {
151 case SW_DOOR5: return 90;
153 return 0;
156 void SW_cheat_open (void) {
157 int i;
159 for(i=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) switch(sw[i].t) {
160 case SW_DOOR: case SW_DOOR5:
161 case SW_OPENDOOR:
162 if(fld[sw[i].b][sw[i].a]!=2) break;
163 SW_press(sw[i].x*CELW+4,sw[i].y*CELH+4,1,1,0xFF,-3);
164 break;
168 int SW_press (int x, int y, int r, int h, byte t, int o) {
169 int sx,sy,i,p;
171 sx=(x-r)/CELW;sy=(y-h+1)/CELH;
172 x=(x+r)/CELW;y/=CELH;
173 for(i=p=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) {
174 if(sw[i].x>=sx && sw[i].x<=x && sw[i].y>=sy && sw[i].y<=y && ((sw[i].f&0x8F)&t)) {
175 if(sw[i].f&0x70) if((sw[i].f&(t&0x70))!=(sw[i].f&0x70)) continue;
176 switch(sw[i].t) {
177 case SW_EXIT:
178 g_exit=1;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
179 case SW_EXITS:
180 g_exit=2;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
181 case SW_DOOR: case SW_DOOR5:
182 switch(fld[sw[i].b][sw[i].a]) {
183 case 2:
184 opendoor(i);sw[i].tm=9;sw[i].d=doortime(sw[i].t);break;
185 case 3:
186 if(shutdoor(i)) {sw[i].tm=9;sw[i].d=0;}
187 else {
188 if(!swsnd) swsnd=Z_sound(sndnoway,128);
189 sw[i].d=2;
190 }break;
191 }break;
192 case SW_PRESS:
193 sw[i].tm=9;
194 SW_press((dword)sw[i].a*8+4,(dword)sw[i].b*8+12,8,16,(t&0x70)|0x80,o);
195 break;
196 case SW_TELE:
197 if(o < -2) break;
198 if(!Z_canfit((dword)sw[i].a*8+4,(dword)sw[i].b*8+7,r,h)) {
199 if(!swsnd) swsnd=Z_sound(sndnotele,128);
200 break;
201 }Z_teleobj(o,(dword)sw[i].a*8+4,(dword)sw[i].b*8+7);
202 sw[i].tm=1;
203 break;
204 case SW_OPENDOOR:
205 if(fld[sw[i].b][sw[i].a]!=2) break;
206 opendoor(i);
207 sw[i].tm=1;
208 break;
209 case SW_SHUTDOOR:
210 if(fld[sw[i].b][sw[i].a]!=3) break;
211 if(shutdoor(i)) {sw[i].tm=1;sw[i].d=0;}
212 else {
213 if(!swsnd) swsnd=Z_sound(sndnoway,128);
214 sw[i].d=2;
215 }break;
216 case SW_SHUTTRAP: case SW_TRAP:
217 if(fld[sw[i].b][sw[i].a]!=3) break;
218 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
219 door(sw[i].a,sw[i].b);
220 Z_chktrap(1,100,-3,HIT_TRAP);
221 cht=255;chto=2;
222 door(sw[i].a,sw[i].b);
223 fld_need_remap=1;
224 swsnd=Z_sound(sndswn,128);
225 sw[i].tm=1;sw[i].d=20;
226 break;
227 case SW_LIFT:
228 if(fld[sw[i].b][sw[i].a]==10) {
229 cht=10;chto=9;f_ch=0;
230 }else if(fld[sw[i].b][sw[i].a]==9) {
231 cht=9;chto=10;f_ch=0;
232 }else break;
233 door(sw[i].a,sw[i].b);
234 fld_need_remap=1;
235 swsnd=Z_sound(sndswx,128);
236 sw[i].tm=9;
237 break;
238 case SW_LIFTUP:
239 if(fld[sw[i].b][sw[i].a]!=10) break;
240 cht=10;chto=9;f_ch=0;
241 door(sw[i].a,sw[i].b);
242 fld_need_remap=1;
243 swsnd=Z_sound(sndswx,128);
244 sw[i].tm=1;
245 break;
246 case SW_LIFTDOWN:
247 if(fld[sw[i].b][sw[i].a]!=9) break;
248 cht=9;chto=10;f_ch=0;
249 door(sw[i].a,sw[i].b);
250 fld_need_remap=1;
251 swsnd=Z_sound(sndswx,128);
252 sw[i].tm=1;
253 break;
254 case SW_SECRET:
255 if(o!=-1 && o!=-2) break;
256 if(o==-1) ++pl1.secrets;
257 else ++pl2.secrets;
258 sw[i].tm=1;sw[i].t=0;break;
260 if (sw[i].tm != 0) {
261 R_switch_texture(sw[i].x, sw[i].y);
262 p = 1;
264 if(sw[i].tm==1) sw[i].tm=0;
267 return p;