DEADSOFTWARE

files: move resource manager to system drivers
[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 "monster.h"
29 #include "render.h"
31 int sw_secrets;
32 sw_t sw[MAXSW];
34 static void *sndswn, *sndswx, *sndnoway, *sndbdo, *sndbdc, *sndnotele;
35 static int swsnd;
36 static byte cht, chto, chf, f_ch;
38 void SW_alloc (void) {
39 sndswn=Z_getsnd("SWTCHN");
40 sndswx=Z_getsnd("SWTCHX");
41 sndnoway=Z_getsnd("NOWAY");
42 sndbdo=Z_getsnd("BDOPN");
43 sndbdc=Z_getsnd("BDCLS");
44 sndnotele=Z_getsnd("NOTELE");
45 }
47 void SW_init (void) {
48 int i;
49 for (i = 0; i < MAXSW; i++) {
50 sw[i].t = 0;
51 }
52 swsnd = 0;
53 }
55 static void door(byte x,byte y) {
56 byte ex;
58 if(x>=FLDW || y>=FLDH) return;
59 if(fld[y][x]!=cht) return;
60 ex=x+1;
61 for(;x && fld[y][x-1]==cht;--x);
62 for(;ex<FLDW && fld[y][ex]==cht;++ex);
63 memset(fld[y]+x,chto,ex-x);
64 if(f_ch) memset(fldf[y]+x,chf,ex-x);
65 for(;x<ex;++x) {
66 door(x,y-1);
67 door(x,y+1);
68 }
69 }
71 void Z_water_trap (obj_t *o) {
72 int i,j,sx,sy,x,y;
74 if((y=o->y)>=FLDH*CELH+o->h) return;
75 if((x=o->x)<0 || o->x>FLDW*CELW) return;
76 sx=(x-o->r)/CELW;
77 sy=(y-o->h+1)/CELH;
78 x=(x+o->r)/CELW;
79 y=(y-o->h/2)/CELH;
80 for(i=sx;i<=x;++i)
81 for(j=sy;j<=y;++j)
82 if(fld[j][i]==5) {
83 cht=5;chto=255;f_ch=0;
84 door(i,j);
85 }
86 }
88 void Z_untrap (byte t) {
89 byte *p;
90 word n;
92 for(p=(byte*)fld,n=FLDW*FLDH;n;--n,++p)
93 if(*p==255) *p=t;
94 }
96 static void opendoor(int i) {
97 int j;
99 swsnd=Z_sound(sndbdo,128);
100 j=fldf[sw[i].b][sw[i].a];
101 cht=2;chto=3;chf=0;f_ch=1;
102 door(sw[i].a,sw[i].b);
103 fldf[sw[i].b][sw[i].a]=j;
104 fld_need_remap=1;
107 static int shutdoor(int i) {
108 int j;
110 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
111 door(sw[i].a,sw[i].b);
112 cht=255;
113 if(Z_chktrap(0,0,-3,HIT_SOME)) {
114 j=fldf[sw[i].b][sw[i].a];
115 chto=3;chf=0;f_ch=1;
116 door(sw[i].a,sw[i].b);
117 fldf[sw[i].b][sw[i].a]=j;
118 return 0;
120 chto=2;
121 door(sw[i].a,sw[i].b);
122 fld_need_remap=1;
123 swsnd=Z_sound(sndbdc,128);
124 return 1;
127 void SW_act (void) {
128 int i;
130 if(swsnd) --swsnd;
131 for(i=0;i<MAXSW;++i) if(sw[i].t) {
132 if(sw[i].tm) --sw[i].tm;
133 switch(sw[i].t) {
134 case SW_DOOR5: case SW_DOOR: case SW_SHUTDOOR:
135 if(!sw[i].d) break;
136 if(fld[sw[i].b][sw[i].a]!=3) {sw[i].d=0;break;}
137 if(--sw[i].d==0) if(!shutdoor(i)) sw[i].d=9;
138 break;
139 case SW_TRAP:
140 if(!sw[i].d) break;
141 if(fld[sw[i].b][sw[i].a]!=2) {sw[i].d=0;break;}
142 if(--sw[i].d==0) {opendoor(i);sw[i].tm=18;}
143 break;
148 static int doortime(int t) {
149 switch(t) {
150 case SW_DOOR5: return 90;
152 return 0;
155 void SW_cheat_open (void) {
156 int i;
158 for(i=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) switch(sw[i].t) {
159 case SW_DOOR: case SW_DOOR5:
160 case SW_OPENDOOR:
161 if(fld[sw[i].b][sw[i].a]!=2) break;
162 SW_press(sw[i].x*CELW+4,sw[i].y*CELH+4,1,1,0xFF,-3);
163 break;
167 int SW_press (int x, int y, int r, int h, byte t, int o) {
168 int sx,sy,i,p;
170 sx=(x-r)/CELW;sy=(y-h+1)/CELH;
171 x=(x+r)/CELW;y/=CELH;
172 for(i=p=0;i<MAXSW;++i) if(sw[i].t && !sw[i].tm) {
173 if(sw[i].x>=sx && sw[i].x<=x && sw[i].y>=sy && sw[i].y<=y && ((sw[i].f&0x8F)&t)) {
174 if(sw[i].f&0x70) if((sw[i].f&(t&0x70))!=(sw[i].f&0x70)) continue;
175 switch(sw[i].t) {
176 case SW_EXIT:
177 g_exit=1;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
178 case SW_EXITS:
179 g_exit=2;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break;
180 case SW_DOOR: case SW_DOOR5:
181 switch(fld[sw[i].b][sw[i].a]) {
182 case 2:
183 opendoor(i);sw[i].tm=9;sw[i].d=doortime(sw[i].t);break;
184 case 3:
185 if(shutdoor(i)) {sw[i].tm=9;sw[i].d=0;}
186 else {
187 if(!swsnd) swsnd=Z_sound(sndnoway,128);
188 sw[i].d=2;
189 }break;
190 }break;
191 case SW_PRESS:
192 sw[i].tm=9;
193 SW_press((dword)sw[i].a*8+4,(dword)sw[i].b*8+12,8,16,(t&0x70)|0x80,o);
194 break;
195 case SW_TELE:
196 if(o < -2) break;
197 if(!Z_canfit((dword)sw[i].a*8+4,(dword)sw[i].b*8+7,r,h)) {
198 if(!swsnd) swsnd=Z_sound(sndnotele,128);
199 break;
200 }Z_teleobj(o,(dword)sw[i].a*8+4,(dword)sw[i].b*8+7);
201 sw[i].tm=1;
202 break;
203 case SW_OPENDOOR:
204 if(fld[sw[i].b][sw[i].a]!=2) break;
205 opendoor(i);
206 sw[i].tm=1;
207 break;
208 case SW_SHUTDOOR:
209 if(fld[sw[i].b][sw[i].a]!=3) break;
210 if(shutdoor(i)) {sw[i].tm=1;sw[i].d=0;}
211 else {
212 if(!swsnd) swsnd=Z_sound(sndnoway,128);
213 sw[i].d=2;
214 }break;
215 case SW_SHUTTRAP: case SW_TRAP:
216 if(fld[sw[i].b][sw[i].a]!=3) break;
217 cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1;
218 door(sw[i].a,sw[i].b);
219 Z_chktrap(1,100,-3,HIT_TRAP);
220 cht=255;chto=2;
221 door(sw[i].a,sw[i].b);
222 fld_need_remap=1;
223 swsnd=Z_sound(sndswn,128);
224 sw[i].tm=1;sw[i].d=20;
225 break;
226 case SW_LIFT:
227 if(fld[sw[i].b][sw[i].a]==10) {
228 cht=10;chto=9;f_ch=0;
229 }else if(fld[sw[i].b][sw[i].a]==9) {
230 cht=9;chto=10;f_ch=0;
231 }else break;
232 door(sw[i].a,sw[i].b);
233 fld_need_remap=1;
234 swsnd=Z_sound(sndswx,128);
235 sw[i].tm=9;
236 break;
237 case SW_LIFTUP:
238 if(fld[sw[i].b][sw[i].a]!=10) break;
239 cht=10;chto=9;f_ch=0;
240 door(sw[i].a,sw[i].b);
241 fld_need_remap=1;
242 swsnd=Z_sound(sndswx,128);
243 sw[i].tm=1;
244 break;
245 case SW_LIFTDOWN:
246 if(fld[sw[i].b][sw[i].a]!=9) break;
247 cht=9;chto=10;f_ch=0;
248 door(sw[i].a,sw[i].b);
249 fld_need_remap=1;
250 swsnd=Z_sound(sndswx,128);
251 sw[i].tm=1;
252 break;
253 case SW_SECRET:
254 if(o!=-1 && o!=-2) break;
255 if(o==-1) ++pl1.secrets;
256 else ++pl2.secrets;
257 sw[i].tm=1;sw[i].t=0;break;
259 if (sw[i].tm != 0) {
260 R_switch_texture(sw[i].x, sw[i].y);
261 p = 1;
263 if(sw[i].tm==1) sw[i].tm=0;
266 return p;