/* Copyright (C) 1996-1997 Aleksey Volynskov * Copyright (C) 2011 Rambo * Copyright (C) 2020 SovietPony * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License ONLY. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "glob.h" #include #include "view.h" #include "bmap.h" #include "dots.h" #include "smoke.h" #include "weapons.h" #include "misc.h" #include "files.h" #include "game.h" #include "player.h" #include "monster.h" #include "switch.h" #include "my.h" enum{NONE=0,ROCKET,PLASMA,APLASMA,BALL1,BALL2,BALL7,BFGBALL,BFGHIT, MANF,REVF,FIRE}; weapon_t wp[MAXWPN]; static void *snd[14]; static void throw(int,int,int,int,int,int,int,int); void WP_alloc (void) { int i; static char nm[14][6]={ "PISTOL", "SHOTGN", "DSHTGN", "RLAUNC", "RXPLOD", "PLASMA", "FIRSHT", "FIRXPL", "BAREXP", "PUNCH", "SAWHIT", "MGUN", "SPARK1", "SPARK2" }; for(i=0;i<14;++i) snd[i]=Z_getsnd(nm[i]); } void WP_init (void) { int i; for(i=0;i=2) {if(++wp[i].s>=8) wp[i].t=0; break;} if(st&Z_HITAIR) Z_set_speed(&wp[i].o,12); if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND)) { wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[4],128); Z_explode(wp[i].o.x,wp[i].o.y,30,wp[i].own);break;} else if(Z_hit(&wp[i].o,10,wp[i].own,HIT_SOME)) { wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[4],128); Z_explode(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,30,wp[i].own);break;} bfg_fly(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,wp[i].own); break; case PLASMA: case APLASMA: if(st&Z_INWATER) { Z_sound(snd[12],128); Z_water_trap(&wp[i].o); Z_chktrap(1,10,wp[i].own,HIT_ELECTRO); Z_untrap(5); wp[i].t=0;break; } case BALL1: case BALL7: case BALL2: case MANF: if(wp[i].s>=2) {if(++wp[i].s>=((wp[i].t==BALL1 || wp[i].t==BALL7 || wp[i].t==BALL2 || wp[i].t==MANF)?8:12)) wp[i].t=0; break;} if(st&Z_HITAIR) Z_set_speed(&wp[i].o,16); if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND)) {wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[7],128);break;} else if(Z_hit(&wp[i].o,(wp[i].t==BALL7 || wp[i].t==MANF)?40:((wp[i].t==BALL2)?20:5),wp[i].own,HIT_SOME)) {wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[7],128);break;} wp[i].s^=1;break; case BFGBALL: if(st&Z_INWATER) { Z_sound(snd[8],40);Z_sound(snd[13],128); Z_water_trap(&wp[i].o); Z_chktrap(1,1000,wp[i].own,HIT_ELECTRO); Z_untrap(5); wp[i].t=0;break; } if(wp[i].s>=2) {if(++wp[i].s>=14) wp[i].t=0; break;} else if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND)) { Z_bfg9000(wp[i].o.x,wp[i].o.y,wp[i].own); wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[8],128);break;} else if(Z_hit(&wp[i].o,100,wp[i].own,HIT_BFG)) { Z_bfg9000(wp[i].o.x,wp[i].o.y,wp[i].own); wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[8],128);break;} bfg_fly(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,wp[i].own); wp[i].s^=1;break; case BFGHIT: if(++wp[i].s>=8) wp[i].t=0; break; default: break; } } } void WP_gun (int x, int y, int xd, int yd, int o, int v) { register dword d,m; int sx,sy,lx,ly; dword xe,ye,s; byte f; f=BM_MONSTER|BM_WALL; if(o!=-1) f|=BM_PLR1; if(o!=-2) f|=BM_PLR2; if((xd-=x)>0) sx=1; else if(xd<0) sx=-1; else sx=0; if((yd-=y)>0) sy=1; else if(yd<0) sy=-1; else sy=0; if(!xd && !yd) return; if((xd=abs(xd)) > (yd=abs(yd))) d=xd; else d=yd; hit_xv=xd*10/d*sx; hit_yv=yd*10/d*sy; xe=ye=0; lx=x;ly=y; for(;;) { if(x<0 || x>=FLDW*8 || y<0 || y>=FLDH*8) break; if(((m=bmap[y>>5][x>>5])&f)) { if(m&BM_WALL) if(fld[y>>3][x>>3]==1 || fld[y>>3][x>>3]==2) { for(x=lx,y=ly,xe=ye=0;fld[y>>3][x>>3]!=1 && fld[y>>3][x>>3]!=2;) { lx=x;ly=y; if((xe+=xd)>=d) {xe-=d;x+=sx;} if((ye+=yd)>=d) {ye-=d;y+=sy;} } DOT_spark(lx,ly,sx*10,sy*10,1); break; } if(m&(BM_MONSTER|BM_PLR1|BM_PLR2)) if(Z_gunhit(x,y,o,sx*v,sy*v)) break; lx=x;ly=y; if((xe+=(xd<<3))>=d) { x+=xe/d*sx;xe=xe%d; } if((ye+=(yd<<3))>=d) { y+=ye/d*sy;ye=ye%d; } }else{ if(sx==0) m=0; else{m=x&31;if(sx>0) m^=31; ++m;} if(sy==0) s=0; else{s=y&31;if(sy>0) s^=31; ++s;} if((s=x)?1:0; wp[i].own=o; throw(i,x,y,xd,yd,2,5,12); return; } } void WP_revf (int x, int y, int xd, int yd, int o, int t) { int i; for(i=0;i=x)?1:0; wp[i].own=o;wp[i].target=t; throw(i,x,y,xd,yd,2,5,12); return; } } void WP_plasma (int x, int y, int xd, int yd, int o) { int i; for(i=0;i=0;--i) { j=myrand(10*2+1)-10; WP_gun(x,y+j,xd,yd+j,o,(i%3)?0:1); } } void WP_ognemet (int x, int y, int xd, int yd, int xv, int yv, int o) { int m; m=abs(xd-x);if(!m) m=abs(yd-y); SMK_flame(x,y,xv,yv,2,2,(xd-x)*3000/m,(yd-y)*3000/m,1,o); }