DEADSOFTWARE

126fd5ce4e24e5f80fbc1e39895917cb3dc8fb75
[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"
35 extern map_block_t blk;
37 #pragma pack(1)
38 typedef struct{
39 obj_t o;
40 int t;
41 int s;
42 }item_t;
43 #pragma pack()
45 static void *snd[4],*spr[58];
46 static char sprd[58];
47 static int tsndtm,rsndtm;
48 static item_t it[MAXITEM];
50 int itm_rtime=1092;
52 void IT_savegame(FILE* h) {
53 int n;
55 for(n=MAXITEM;--n;) if(it[n].t) break;
56 ++n;myfwrite(&n,1,4,h);
57 myfwrite(it,1,n*sizeof(it[0]),h);
58 myfwrite(&itm_rtime,1,4,h);
59 }
61 void IT_loadgame(FILE* h) {
62 int n;
64 myfread(&n,1,4,h);
65 myfread(it,1,n*sizeof(it[0]),h);
66 myfread(&itm_rtime,1,4,h);
67 }
69 void IT_alloc(void) {
70 int i,j,n;
71 static char nm[][6]={
72 "ITEMUP","WPNUP","GETPOW","ITMBK"
73 },snm[][4]={
74 "CLIP","SHEL","ROCK","CELL","AMMO","SBOX","BROK","CELP",
75 "STIM","MEDI","BPAK",
76 "CSAW","SHOT","SGN2","MGUN","LAUN","PLAS","BFUG"
77 },n4[][4]={
78 "SOUL","SMRT","SMGT","SMBT"
79 },n3[][4]={
80 "GOR1","FCAN"
81 };
83 // logo(" items");
84 for(i=0;i<18;++i) spr[i]=Z_getspr(snm[i],0,0,sprd+i);
85 for(;i<20;++i) {
86 spr[i]=Z_getspr("ARM1",i-18,0,sprd+i);
87 spr[i+2]=Z_getspr("ARM2",i-18,0,sprd+i);
88 }i+=2;
89 for(;i<26;++i) spr[i]=Z_getspr("MEGA",i-22,0,sprd+i);
90 for(;i<30;++i) spr[i]=Z_getspr("PINV",i-26,0,sprd+i);
91 spr[30]=Z_getspr("AQUA",0,0,sprd+30);
92 spr[31]=Z_getspr("KEYR",0,0,sprd+31);
93 spr[32]=Z_getspr("KEYG",0,0,sprd+32);
94 spr[33]=Z_getspr("KEYB",0,0,sprd+33);
95 spr[34]=Z_getspr("SUIT",0,0,sprd+34);
96 for(n=35,j=0;j<4;++j)
97 for(i=0;i<4;++i,++n) spr[n]=Z_getspr(n4[j],i,0,sprd+n);
98 for(j=0;j<2;++j)
99 for(i=0;i<3;++i,++n) spr[n]=Z_getspr(n3[j],i,0,sprd+n);
100 spr[57]=Z_getspr("GUN2",0,0,sprd+57);
101 for(i=0;i<4;++i) snd[i]=Z_getsnd(nm[i]);
102 for(i=0;i<MAXITEM;++i) {it[i].o.r=10;it[i].o.h=8;}
105 void IT_init(void) {
106 int i;
108 for(i=0;i<MAXITEM;++i) {
109 it[i].t=I_NONE;
110 it[i].o.xv=it[i].o.yv=it[i].o.vx=it[i].o.vy=0;
112 tsndtm=rsndtm=0;
115 int IT_load(FILE* h) {
116 int m,i,j;
117 old_thing_t t;
119 switch(blk.t) {
120 case MB_THING:
121 for(i=0;blk.sz>0;++i,blk.sz-=8) {
122 myfread(&t,1,sizeof(t),h);
123 t.x = short2host(t.x);
124 t.y = short2host(t.y);
125 t.t = short2host(t.t);
126 t.f = short2host(t.f);
127 it[i].o.x=t.x;it[i].o.y=t.y;
128 it[i].t=t.t;it[i].s=t.f;
129 if(!it[i].t) break;
130 if((it[i].s&THF_DM) && !g_dm) it[i].t=0;
131 }m=i;
132 for(i=0,j=-1;i<m;++i) if(it[i].t==TH_PLR1) {j=i;it[i].t=0;}
133 if(!g_dm) {
134 if(j==-1) ERR_fatal("Предмет игрок_1 не найден");
135 dm_pos[0].x=it[j].o.x;dm_pos[0].y=it[j].o.y;dm_pos[0].d=it[j].s&THF_DIR;
137 for(i=0,j=-1;i<m;++i) if(it[i].t==TH_PLR2) {j=i;it[i].t=0;}
138 if(!g_dm && _2pl) {
139 if(j==-1) ERR_fatal("Предмет игрок_2 не найден");
140 dm_pos[1].x=it[j].o.x;dm_pos[1].y=it[j].o.y;dm_pos[1].d=it[j].s&THF_DIR;
142 for(i=0,j=0;i<m;++i) if(it[i].t==TH_DMSTART) {
143 if(g_dm)
144 {dm_pos[j].x=it[i].o.x;dm_pos[j].y=it[i].o.y;dm_pos[j].d=it[i].s&THF_DIR;}
145 it[i].t=0;++j;
147 if(g_dm && j<2) ERR_fatal("Меньше 2-ух точек DM");
148 if(g_dm) {
149 dm_pnum=j;
150 dm_pl1p=myrand(dm_pnum);
151 do{ dm_pl2p=myrand(dm_pnum); }while(dm_pl2p==dm_pl1p);
152 }else {dm_pl1p=0;dm_pl2p=1;dm_pnum=2;}
153 PL_spawn(&pl1,dm_pos[dm_pl1p].x,dm_pos[dm_pl1p].y,dm_pos[dm_pl1p].d);
154 if(_2pl) PL_spawn(&pl2,dm_pos[dm_pl2p].x,dm_pos[dm_pl2p].y,dm_pos[dm_pl2p].d);
155 for(i=0;i<m;++i)
156 if(it[i].t>=TH_CLIP && it[i].t<TH_DEMON) {
157 it[i].s=0;it[i].t=it[i].t-TH_CLIP+I_CLIP;
158 if(it[i].t>=I_KEYR && it[i].t<=I_KEYB) it[i].t|=0x8000;
159 }else if(it[i].t>=TH_DEMON) {
160 MN_spawn(it[i].o.x,it[i].o.y,it[i].s&THF_DIR,it[i].t-TH_DEMON+MN_DEMON);
161 it[i].t=0;
163 return 1;
164 }return 0;
167 static void takesnd(int t) {
168 if(tsndtm) return;
169 t&=0x7FFF;
170 if(t<=I_CELP || (t>=I_BPACK && t<=I_BFG) || t==I_GUN2)
171 {tsndtm=Z_sound(snd[1],128);return;}
172 if(t==I_MEGA || t==I_INVL || t==I_SUPER)
173 {tsndtm=Z_sound(snd[2],192);return;}
174 tsndtm=Z_sound(snd[0],256);
177 void IT_act(void) {
178 int i,j;
180 if(tsndtm) --tsndtm;
181 if(rsndtm) --rsndtm;
182 for(i=0;i<MAXITEM;++i) if(it[i].t)
183 if(it[i].s<0) {
184 if(++it[i].s==-8) {
185 FX_ifog(it[i].o.x,it[i].o.y);
186 if(!rsndtm) rsndtm=Z_sound(snd[3],128);
188 }else{
189 switch(it[i].t) {
190 case I_ARM1: case I_ARM2:
191 if(++it[i].s>=18) it[i].s=0; break;
192 case I_MEGA: case I_INVL:
193 case I_SUPER: case I_RTORCH: case I_GTORCH: case I_BTORCH:
194 if(++it[i].s>=8) it[i].s=0; break;
195 case I_GOR1: case I_FCAN:
196 if(++it[i].s>=6) it[i].s=0; break;
198 if(it[i].t&0x8000) {
199 if((j=Z_moveobj(&it[i].o))&Z_FALLOUT) {it[i].t=0;continue;}
200 else if(j&Z_HITWATER) Z_splash(&it[i].o,it[i].o.r+it[i].o.h);
202 if(Z_overlap(&it[i].o,&pl1.o))
203 if(PL_give(&pl1,it[i].t&0x7FFF)) {
204 takesnd(it[i].t);
205 if(_2pl) if((it[i].t&0x7FFF)>=I_KEYR && (it[i].t&0x7FFF)<=I_KEYB) continue;
206 if(!(it[i].s=-itm_rtime) || (it[i].t&0x8000)) it[i].t=0;
207 continue;
209 if(_2pl) if(Z_overlap(&it[i].o,&pl2.o))
210 if(PL_give(&pl2,it[i].t&0x7FFF)) {
211 takesnd(it[i].t);
212 if((it[i].t&0x7FFF)>=I_KEYR && (it[i].t&0x7FFF)<=I_KEYB) continue;
213 if(!(it[i].s=-itm_rtime) || (it[i].t&0x8000)) it[i].t=0;
214 continue;
219 void IT_draw(void) {
220 int i,s;
222 for(i=0;i<MAXITEM;++i) {
223 s=-1;
224 if(it[i].t && it[i].s>=0) switch(it[i].t&0x7FFF) {
225 case I_ARM1:
226 s=it[i].s/9+18;break;
227 case I_ARM2:
228 s=it[i].s/9+20;break;
229 case I_MEGA:
230 s=it[i].s/2+22;break;
231 case I_INVL:
232 s=it[i].s/2+26;break;
233 case I_SUPER: case I_RTORCH: case I_GTORCH: case I_BTORCH:
234 s=it[i].s/2+(it[i].t-I_SUPER)*4+35;break;
235 case I_GOR1: case I_FCAN:
236 s=it[i].s/2+(it[i].t-I_GOR1)*3+51;break;
237 case I_AQUA: s=30;break;
238 case I_SUIT: s=34;break;
239 case I_KEYR: case I_KEYG: case I_KEYB:
240 s=(it[i].t&0x7FFF)-I_KEYR+31;break;
241 case I_GUN2: s=57;break;
242 default:
243 s=(it[i].t&0x7FFF)-1;
245 if(s>=0) Z_drawspr(it[i].o.x,it[i].o.y,spr[s],sprd[s]);
249 void IT_spawn(int x,int y,int t) {
250 int i;
252 for(i=0;i<MAXITEM;++i) if(!it[i].t) {
253 it[i].t=t|0x8000;it[i].s=0;
254 it[i].o.x=x;it[i].o.y=y;
255 it[i].o.xv=it[i].o.yv=it[i].o.vx=it[i].o.vy=0;
256 it[i].o.r=10;it[i].o.h=8;
257 return;
261 void IT_drop_ammo(int t,int n,int x,int y) {
262 static int an[8]={10,4,1,40,50,25,5,100};
263 int a;
265 again:;
266 for(a=an[t-I_CLIP];n>=a;n-=a)
267 IT_spawn(x+myrand(3*2+1)-3,y-myrand(7),t);
268 if(t>=I_AMMO) {t-=4;goto again;}