DEADSOFTWARE

fix some warnings
[flatwaifu.git] / src / items.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 <stdlib.h>
25 #include "error.h"
26 #include "view.h"
27 #include "items.h"
28 #include "fx.h"
29 #include "player.h"
30 #include "monster.h"
31 #include "things.h"
32 #include "misc.h"
33 #include "map.h"
34 #include "my.h"
36 extern map_block_t blk;
38 #pragma pack(1)
39 typedef struct{
40 obj_t o;
41 int t;
42 int s;
43 }item_t;
44 #pragma pack()
46 static void *snd[4],*spr[58];
47 static char sprd[58];
48 static int tsndtm,rsndtm;
49 static item_t it[MAXITEM];
51 int itm_rtime=1092;
53 void IT_savegame (FILE *h) {
54 int i, n;
55 for (n = MAXITEM - 1; n >= 0 && it[n].t == 0; n--) {
56 // empty
57 }
58 n += 1;
59 myfwrite32(n, h);
60 for (i = 0; i < n; i++) {
61 myfwrite32(it[i].o.x, h);
62 myfwrite32(it[i].o.y, h);
63 myfwrite32(it[i].o.xv, h);
64 myfwrite32(it[i].o.yv, h);
65 myfwrite32(it[i].o.vx, h);
66 myfwrite32(it[i].o.vy, h);
67 myfwrite32(it[i].o.r, h);
68 myfwrite32(it[i].o.h, h);
69 myfwrite32(it[i].t, h);
70 myfwrite32(it[i].s, h);
71 }
72 myfwrite32(itm_rtime, h);
73 }
75 void IT_loadgame (FILE *h) {
76 int i, n;
77 n = myfread32(h);
78 for (i = 0; i < n; i++) {
79 it[i].o.x = myfread32(h);
80 it[i].o.y = myfread32(h);
81 it[i].o.xv = myfread32(h);
82 it[i].o.yv = myfread32(h);
83 it[i].o.vx = myfread32(h);
84 it[i].o.vy = myfread32(h);
85 it[i].o.r = myfread32(h);
86 it[i].o.h = myfread32(h);
87 it[i].t = myfread32(h);
88 it[i].s = myfread32(h);
89 }
90 itm_rtime = myfread32(h);
91 }
93 void IT_alloc(void) {
94 int i,j,n;
95 static char nm[][6]={
96 "ITEMUP","WPNUP","GETPOW","ITMBK"
97 },snm[][4]={
98 "CLIP","SHEL","ROCK","CELL","AMMO","SBOX","BROK","CELP",
99 "STIM","MEDI","BPAK",
100 "CSAW","SHOT","SGN2","MGUN","LAUN","PLAS","BFUG"
101 },n4[][4]={
102 "SOUL","SMRT","SMGT","SMBT"
103 },n3[][4]={
104 "GOR1","FCAN"
105 };
107 // logo(" items");
108 for(i=0;i<18;++i) spr[i]=Z_getspr(snm[i],0,0,sprd+i);
109 for(;i<20;++i) {
110 spr[i]=Z_getspr("ARM1",i-18,0,sprd+i);
111 spr[i+2]=Z_getspr("ARM2",i-18,0,sprd+i);
112 }i+=2;
113 for(;i<26;++i) spr[i]=Z_getspr("MEGA",i-22,0,sprd+i);
114 for(;i<30;++i) spr[i]=Z_getspr("PINV",i-26,0,sprd+i);
115 spr[30]=Z_getspr("AQUA",0,0,sprd+30);
116 spr[31]=Z_getspr("KEYR",0,0,sprd+31);
117 spr[32]=Z_getspr("KEYG",0,0,sprd+32);
118 spr[33]=Z_getspr("KEYB",0,0,sprd+33);
119 spr[34]=Z_getspr("SUIT",0,0,sprd+34);
120 for(n=35,j=0;j<4;++j)
121 for(i=0;i<4;++i,++n) spr[n]=Z_getspr(n4[j],i,0,sprd+n);
122 for(j=0;j<2;++j)
123 for(i=0;i<3;++i,++n) spr[n]=Z_getspr(n3[j],i,0,sprd+n);
124 spr[57]=Z_getspr("GUN2",0,0,sprd+57);
125 for(i=0;i<4;++i) snd[i]=Z_getsnd(nm[i]);
126 for(i=0;i<MAXITEM;++i) {it[i].o.r=10;it[i].o.h=8;}
129 void IT_init(void) {
130 int i;
132 for(i=0;i<MAXITEM;++i) {
133 it[i].t=I_NONE;
134 it[i].o.xv=it[i].o.yv=it[i].o.vx=it[i].o.vy=0;
136 tsndtm=rsndtm=0;
139 int IT_load (FILE *h) {
140 int m, i, j;
141 old_thing_t t;
142 switch (blk.t) {
143 case MB_THING:
144 for (i = 0; blk.sz > 0; ++i, blk.sz -= 8) {
145 t.x = myfread16(h);
146 t.y = myfread16(h);
147 t.t = myfread16(h);
148 t.f = myfread16(h);
149 it[i].o.x = t.x;
150 it[i].o.y = t.y;
151 it[i].t = t.t;
152 it[i].s = t.f;
153 if (it[i].t && (it[i].s & THF_DM) && !g_dm) {
154 it[i].t=0;
157 m = i;
158 for (i = 0, j = -1; i < m; ++i) {
159 if (it[i].t == TH_PLR1) {
160 j = i;
161 it[i].t = 0;
164 if (!g_dm) {
165 if (j == -1) {
166 ERR_fatal("Предмет игрок_1 не найден");
168 dm_pos[0].x = it[j].o.x;
169 dm_pos[0].y = it[j].o.y;
170 dm_pos[0].d = it[j].s & THF_DIR;
172 for (i = 0, j = -1; i < m; ++i) {
173 if (it[i].t == TH_PLR2) {
174 j = i;
175 it[i].t = 0;
178 if (!g_dm && _2pl) {
179 if (j == -1) {
180 ERR_fatal("Предмет игрок_2 не найден");
182 dm_pos[1].x = it[j].o.x;
183 dm_pos[1].y = it[j].o.y;
184 dm_pos[1].d = it[j].s & THF_DIR;
186 for (i = 0, j = 0; i < m; ++i) {
187 if (it[i].t == TH_DMSTART) {
188 if (g_dm) {
189 dm_pos[j].x = it[i].o.x;
190 dm_pos[j].y = it[i].o.y;
191 dm_pos[j].d = it[i].s & THF_DIR;
193 it[i].t = 0;
194 ++j;
197 if (g_dm && j < 2) {
198 ERR_fatal("Меньше 2-ух точек DM");
200 if (g_dm) {
201 dm_pnum = j;
202 dm_pl1p = myrand(dm_pnum);
203 do {
204 dm_pl2p = myrand(dm_pnum);
205 } while (dm_pl2p == dm_pl1p);
206 } else {
207 dm_pl1p = 0;
208 dm_pl2p = 1;
209 dm_pnum = 2;
211 PL_spawn(&pl1, dm_pos[dm_pl1p].x, dm_pos[dm_pl1p].y, dm_pos[dm_pl1p].d);
212 if (_2pl) {
213 PL_spawn(&pl2, dm_pos[dm_pl2p].x, dm_pos[dm_pl2p].y, dm_pos[dm_pl2p].d);
215 for (i = 0; i < m; ++i) {
216 if (it[i].t >= TH_CLIP && it[i].t < TH_DEMON) {
217 it[i].s = 0;
218 it[i].t = it[i].t - TH_CLIP + I_CLIP;
219 if (it[i].t >= I_KEYR && it[i].t <= I_KEYB) {
220 it[i].t |= 0x8000;
222 } else if (it[i].t >= TH_DEMON) {
223 MN_spawn(it[i].o.x, it[i].o.y, it[i].s & THF_DIR, it[i].t - TH_DEMON + MN_DEMON);
224 it[i].t = 0;
227 return 1;
229 return 0;
232 static void takesnd(int t) {
233 if(tsndtm) return;
234 t&=0x7FFF;
235 if(t<=I_CELP || (t>=I_BPACK && t<=I_BFG) || t==I_GUN2)
236 {tsndtm=Z_sound(snd[1],128);return;}
237 if(t==I_MEGA || t==I_INVL || t==I_SUPER)
238 {tsndtm=Z_sound(snd[2],192);return;}
239 tsndtm=Z_sound(snd[0],256);
242 void IT_act(void) {
243 int i,j;
245 if(tsndtm) --tsndtm;
246 if(rsndtm) --rsndtm;
247 for(i=0;i<MAXITEM;++i) if(it[i].t)
248 if(it[i].s<0) {
249 if(++it[i].s==-8) {
250 FX_ifog(it[i].o.x,it[i].o.y);
251 if(!rsndtm) rsndtm=Z_sound(snd[3],128);
253 }else{
254 switch(it[i].t) {
255 case I_ARM1: case I_ARM2:
256 if(++it[i].s>=18) it[i].s=0; break;
257 case I_MEGA: case I_INVL:
258 case I_SUPER: case I_RTORCH: case I_GTORCH: case I_BTORCH:
259 if(++it[i].s>=8) it[i].s=0; break;
260 case I_GOR1: case I_FCAN:
261 if(++it[i].s>=6) it[i].s=0; break;
263 if(it[i].t&0x8000) {
264 if((j=Z_moveobj(&it[i].o))&Z_FALLOUT) {it[i].t=0;continue;}
265 else if(j&Z_HITWATER) Z_splash(&it[i].o,it[i].o.r+it[i].o.h);
267 if(Z_overlap(&it[i].o,&pl1.o))
268 if(PL_give(&pl1,it[i].t&0x7FFF)) {
269 takesnd(it[i].t);
270 if(_2pl) if((it[i].t&0x7FFF)>=I_KEYR && (it[i].t&0x7FFF)<=I_KEYB) continue;
271 if(!(it[i].s=-itm_rtime) || (it[i].t&0x8000)) it[i].t=0;
272 continue;
274 if(_2pl) if(Z_overlap(&it[i].o,&pl2.o))
275 if(PL_give(&pl2,it[i].t&0x7FFF)) {
276 takesnd(it[i].t);
277 if((it[i].t&0x7FFF)>=I_KEYR && (it[i].t&0x7FFF)<=I_KEYB) continue;
278 if(!(it[i].s=-itm_rtime) || (it[i].t&0x8000)) it[i].t=0;
279 continue;
284 void IT_draw(void) {
285 int i,s;
287 for(i=0;i<MAXITEM;++i) {
288 s=-1;
289 if(it[i].t && it[i].s>=0) switch(it[i].t&0x7FFF) {
290 case I_ARM1:
291 s=it[i].s/9+18;break;
292 case I_ARM2:
293 s=it[i].s/9+20;break;
294 case I_MEGA:
295 s=it[i].s/2+22;break;
296 case I_INVL:
297 s=it[i].s/2+26;break;
298 case I_SUPER: case I_RTORCH: case I_GTORCH: case I_BTORCH:
299 s=it[i].s/2+(it[i].t-I_SUPER)*4+35;break;
300 case I_GOR1: case I_FCAN:
301 s=it[i].s/2+(it[i].t-I_GOR1)*3+51;break;
302 case I_AQUA: s=30;break;
303 case I_SUIT: s=34;break;
304 case I_KEYR: case I_KEYG: case I_KEYB:
305 s=(it[i].t&0x7FFF)-I_KEYR+31;break;
306 case I_GUN2: s=57;break;
307 default:
308 s=(it[i].t&0x7FFF)-1;
310 if(s>=0) Z_drawspr(it[i].o.x,it[i].o.y,spr[s],sprd[s]);
314 void IT_spawn(int x,int y,int t) {
315 int i;
317 for(i=0;i<MAXITEM;++i) if(!it[i].t) {
318 it[i].t=t|0x8000;it[i].s=0;
319 it[i].o.x=x;it[i].o.y=y;
320 it[i].o.xv=it[i].o.yv=it[i].o.vx=it[i].o.vy=0;
321 it[i].o.r=10;it[i].o.h=8;
322 return;
326 void IT_drop_ammo(int t,int n,int x,int y) {
327 static int an[8]={10,4,1,40,50,25,5,100};
328 int a;
330 again:;
331 for(a=an[t-I_CLIP];n>=a;n-=a)
332 IT_spawn(x+myrand(3*2+1)-3,y-myrand(7),t);
333 if(t>=I_AMMO) {t-=4;goto again;}