2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23 * related information and legal notices. It is expected that any future
24 * projects/authors will amend these files as needed.
28 * multifire.c: Fire at other sectors/ships
30 * Known contributors to this file:
56 targ_land, targ_ship, targ_sub, targ_unit, targ_bogus
60 struct emp_qelem queue; /* list of fired things */
61 int type; /* ship? otherwise sector */
62 int uid; /* ship uid */
63 coord x,y; /* sector coords */
64 int defdam; /* damage defenders did */
65 int victim; /* who I was shooting at */
74 static int defend(struct emp_qelem *al,
76 enum targ_type target,
77 enum targ_type attacker,
113 enum targ_type target, attacker, orig_attacker;
116 struct nstr_item nbst;
122 struct emp_qelem fired, defended;
130 emp_initque(&defended);
132 while ((type != EF_SECTOR) && (type != EF_SHIP) && (type != EF_LAND)){
133 if (!(p = getstarg(player->argp[1],
134 "Firing from ship(s), sect(s), or land unit(s)? ", buf)))
138 if (type == EF_SECTOR){
139 if (opt_NO_FORT_FIRE) {
140 pr("Fort firing is disabled.\n");
143 orig_attacker = attacker=targ_land;
146 else if (type == EF_SHIP) {
147 orig_attacker = attacker=targ_ship;
149 else if (type == EF_LAND) {
150 orig_attacker = attacker=targ_unit;
153 pr("Please type 'sh', 'l', or 'se'!\n");
155 if ((ptr = getstarg(player->argp[2], "Firing from? ", buf)) == 0 || *ptr == '\0')
158 if (!snxtitem(&nbst, type, ptr))
161 if (player->aborted){
162 pr("Fire aborted.\n");
165 while(nxtitem(&nbst, (s_char *)&item)){
166 attacker = orig_attacker;
167 if (attacker == targ_unit){
168 if (!getland(item.land.lnd_uid, &fland))
170 if (!getsect(item.land.lnd_x,item.land.lnd_y,&fsect))
172 if (item.land.lnd_own != player->cnum)
175 if (fland.lnd_frg == 0){
176 pr("Unit %d cannot fire!\n",fland.lnd_uid);
179 if (lnd_getmil(&fland) < 1) {
180 pr("Unit %d cannot fire because it has no military!\n",
184 if (fland.lnd_ship >= 0){
185 pr("Unit %d cannot fire because it is on a ship!\n",
189 if (fland.lnd_land >= 0){
190 pr("Unit %d cannot fire because it is on a land unit!\n",
194 if (fland.lnd_effic < LAND_MINFIREEFF){
195 pr("Unit %d cannot fire because it is less than %d%% efficient\n",fland.lnd_uid, LAND_MINFIREEFF);
198 resupply_commod(&fland,I_SHELL); /* Get more shells */
199 putland(fland.lnd_uid,&fland);
200 if (getvar(V_SHELL, (s_char *)&fland, EF_LAND) == 0){
201 pr("%s -- not enough shells\n",
206 else if (attacker == targ_ship){
207 if (!getship(item.ship.shp_uid, &fship))
209 if (item.ship.shp_own != player->cnum)
211 if (getvar(V_MILIT, (s_char *)&item.ship, EF_SHIP) < 1){
212 pr("Not enough mil on ship #%d\n",item.ship.shp_uid);
215 gun = getvar(V_GUN, (s_char *)&item.ship, EF_SHIP);
216 gun = min(gun, item.ship.shp_glim);
217 if (item.ship.shp_frnge == 0){
218 pr("Ships %d cannot fire guns!\n",item.ship.shp_uid);
222 pr("Not enough guns on ship #%d\n",item.ship.shp_uid);
225 if (getvar(V_SHELL, (s_char *)&item.ship, EF_SHIP) == 0){
226 pr("Not enough shells on ship #%d\n",item.ship.shp_uid);
229 if (item.ship.shp_effic < 60){
230 pr("Ship #%d is crippled!\n",item.ship.shp_uid);
233 fshipno=fship.shp_uid;
235 else if (attacker == targ_land){
236 if (!getsect(item.sect.sct_x,item.sect.sct_y, &fsect))
238 if (item.sect.sct_own != player->cnum)
240 if (item.sect.sct_type != SCT_FORTR)
242 if (item.sect.sct_effic < ((u_char)FORTEFF)){
243 pr("Fort not efficient enough to fire!\n");
246 if (getvar(V_GUN, (s_char *)&item.sect, EF_SECTOR) == 0){
247 pr("Not enough guns in sector %s!\n",xyas(item.sect.sct_x,item.sect.sct_y,player->cnum));
250 if (getvar(V_SHELL, (s_char *)&item.sect, EF_SECTOR) == 0){
251 pr("Not enough shells in sector %s!\n",xyas(item.sect.sct_x,item.sect.sct_y,player->cnum));
254 if (getvar(V_MILIT, (s_char *)&item.sect, EF_SECTOR) < 5){
255 pr("Not enough military in sector %s!\n",xyas(item.sect.sct_x,item.sect.sct_y,player->cnum));
258 pr("\nSector %s firing\n",
259 xyas(item.sect.sct_x,item.sect.sct_y,player->cnum));
261 if ((ptr = getstarg(player->argp[3], "Firing at? ", buf)) == 0 || *ptr == '\0')
263 if (player->aborted){
264 pr("Fire aborted.\n");
268 (void)strcpy(vbuf, ptr);
273 if (target == targ_ship) {
274 vshipno = atoi(vbuf);
275 if (vshipno < 0 || !getship(vshipno, &vship) ||
277 pr("No such ship exists!\n");
280 target = (mchr[(int)vship.shp_type].m_flags & M_SUB) ?
281 targ_sub : targ_ship;
282 vict = vship.shp_own;
285 if (!getsect(x, y, &vsect)) {
286 pr("No such sector exists!\n");
290 if (!sarg_xy(vbuf, &x, &y) || !getsect(x, y, &vsect)) {
291 pr("No such sector exists!\n");
294 /* We check the sector type, but we only use it for damage, not
295 reporting. That way, you don't get extra information you wouldn't
296 normally get. Besides, what if they want to slam water? :) */
297 if (vsect.sct_type == SCT_SANCT ||
298 vsect.sct_type == SCT_WATER)
302 vict = vsect.sct_own;
306 if (attacker == targ_ship) {
307 shots = -1; /* convert to max later */
308 if (fship.shp_own != player->cnum) {
309 pr("Not your ship!\n");
312 if (target == targ_sub || target == targ_ship) {
313 if (fship.shp_uid == vship.shp_uid) {
314 pr("You can't fire upon yourself!\n");
321 attacker = (mchr[fship.shp_type].m_flags & M_SUB) ?
322 targ_sub : targ_ship;
323 if (attacker == targ_sub){
324 pr("Subs may not fire normally.. use torpedo.\n");
328 attacker = targ_ship;
329 if ((mil = getvar(V_MILIT, (s_char *)&fship, EF_SHIP)) < 1) {
330 pr("Not enough military for firing crew.\n");
333 gun = getvar(V_GUN, (s_char *)&fship, EF_SHIP);
334 gun = min(gun, fship.shp_glim);
335 if (fship.shp_frnge == 0 || gun == 0) {
336 pr("Insufficient arms.\n");
339 shell = getvar(V_SHELL, (s_char *)&fship, EF_SHIP);
341 shell+=supply_commod(fship.shp_own,fship.shp_x,
342 fship.shp_y,I_SHELL,2-shell);
347 if (fship.shp_effic < 60) {
348 pr("Ship #%d is crippled (%d%%)\n", fshipno,
352 range = techfact(fship.shp_tech,
353 (double)fship.shp_frnge / 2.0);
354 range2 = (double)roundrange(range);
355 pr("range is %.2f (%.2f)\n", range2, range);
356 if (target == targ_sub) {
357 if ((mchr[(int)fship.shp_type].m_flags & M_DCH) == 0) {
358 pr("A %s can't drop depth charges!\n",
359 mchr[(int)fship.shp_type].m_name);
363 pr("Not enough shells for depth charge!\n");
367 gun = min(gun, shell*2);
368 gun = min(gun, mil / 2);
370 if (shots > gun || shots < 0)
372 else if (shots == 0) {
373 pr("No shots fired.\n");
376 guneff = seagun(fship.shp_effic, shots);
378 shell -= ldround(((double)shots)/2.0,1);
379 putvar(V_SHELL, shell, (s_char *)&fship, EF_SHIP);
380 putship(fship.shp_uid,&fship);
381 if (opt_NOMOBCOST == 0)
382 fship.shp_mobil = max(fship.shp_mobil - 15, -100);
383 } else if (attacker == targ_unit) {
384 if (fland.lnd_own != player->cnum) {
385 pr("Not your unit!\n");
389 if (target == targ_land) {
390 if (fland.lnd_x == vsect.sct_x && fland.lnd_y == vsect.sct_y) {
391 pr("You can't fire upon yourself!\n");
399 if (fland.lnd_frg == 0){
400 pr("Unit %d cannot fire!\n",fland.lnd_uid);
403 if (getvar(V_SHELL, (s_char *)&fland, EF_LAND) == 0){
404 pr("%s -- not enough shells\n", prland(&fland));
408 shell = getvar(V_SHELL,(s_char *)&fland, EF_LAND);
410 range = techfact((int)fland.lnd_tech,
411 (double)fland.lnd_frg / 2.0);
412 range2 = (double)roundrange(range);
413 pr("range is %.2f (%.2f)\n", range2, range);
414 if (target == targ_sub) {
415 pr("A %s can't drop depth charges!\n",
416 lchr[(int)fland.lnd_type].l_name);
420 gun = getvar(V_GUN, (s_char *)&fland, EF_LAND);
422 pr("%s -- not enough guns\n", prland(&fland));
426 dam = (int)landunitgun(fland.lnd_effic, fland.lnd_dam, gun,
427 fland.lnd_ammo, shell);
428 if (target == targ_ship){
429 if (chance(((double)fland.lnd_acc)/100.0))
430 dam = ldround(((double)dam/2.0),1);
433 resupply_commod(&fland,I_SHELL); /* Get more shells */
434 putland(fland.lnd_uid,&fland);
438 if (fsect.sct_own != player->cnum ||
439 fsect.sct_type != SCT_FORTR) {
440 pr("No fortress at %s\n", xyas(fsect.sct_x,
441 fsect.sct_y,player->cnum));
444 if (target == targ_land) {
445 if (fsect.sct_x == vsect.sct_x && fsect.sct_y == vsect.sct_y) {
446 pr("You can't fire upon yourself!\n");
450 attacker = targ_land;
451 if ((gun = getvar(V_GUN, (s_char *)&fsect, EF_SECTOR)) == 0) {
452 pr("Insufficient arms.\n");
455 shell = getvar(V_SHELL, (s_char *)&fsect, EF_SECTOR);
457 shell+=supply_commod(fsect.sct_own,fsect.sct_x,
458 fsect.sct_y,I_SHELL,1);
463 if (getvar(V_MILIT, (s_char *)&fsect, EF_SECTOR) < 5) {
464 pr("Not enough military for firing crew.\n");
467 if (target == targ_sub) {
468 pr("Target ship not sighted!\n");
473 range = tfactfire(player->cnum, 7.0);
474 if (fsect.sct_effic > 59)
476 range2 = (double)roundrange(range);
477 pr("range is %.2f (%.2f)\n", range2, range);
478 guneff = landgun((int)fsect.sct_effic, gun);
481 putvar(V_SHELL, shell, (s_char *)&fsect, EF_SECTOR);
484 trange = mapdist(x, y, fx, fy);
485 if (trange > range2){
486 pr("Target out of range.\n");
491 pr("Target out of range. Thud.\n");
494 pr("Target ship out of range. Splash.\n");
503 fland.lnd_mission = 0;
504 putland(fland.lnd_uid, &fland);
507 fship.shp_mission = 0;
508 putship(fship.shp_uid, &fship);
513 if (target == targ_bogus) {
514 if (vsect.sct_type == SCT_SANCT) {
515 pr("%s is a %s!!\n", vbuf,
516 dchr[SCT_SANCT].d_name);
518 } else if (vsect.sct_type == SCT_WATER) {
519 pr("You must specify a ship in sector %s!\n",
527 if (!trechk(player->cnum, vict, SEAFIR))
531 if (!trechk(player->cnum, vict, SUBFIR))
536 if (!trechk(player->cnum, vict, LANFIR))
544 if (target == targ_land){
545 natp = getnatp(player->cnum);
546 rel = getrel(natp,vict);
547 if ((rel != AT_WAR) && (player->cnum != vict) &&
548 (vict) && (vsect.sct_oldown != player->cnum)){
549 pr("You're not at war with them!\n");
559 if (vship.shp_rflags & RET_DCHRGED)
560 retreat_ship(&vship,'d');
565 prb = (double)(range2?(trange / range2):1.0);
574 pr("Wind deflects shell%s.\n", splur(shots));
575 /* dam = (int)((double)dam / 2.0);*/
576 dam = (int)((double)dam * (double)((double)(90 - (random() % 11)) / 100.0));
585 nreport(player->cnum, N_SCT_SHELL, vict, 1);
586 if (vict && vict != player->cnum)
588 "Country #%d shelled sector %s for %d damage.\n",
589 player->cnum, xyas(x, y, vict), dam);
590 pr("Shell%s hit sector %s for %d damage.\n",
591 splur(shots), xyas(x, y, player->cnum), dam);
592 /* Ok, it wasn't a bogus target, so do damage. */
593 if (target != targ_bogus)
594 sectdamage(&vsect, dam, 0);
597 nreport(player->cnum, N_SHP_SHELL, vict, 1);
599 if ((target != targ_sub) ||
600 ((vship.shp_rflags & RET_DCHRGED) == 0))
601 check_retreat_and_do_shipdamage(&vship, dam);
603 shipdamage(&vship, dam);
606 "Country #%d shelled %s in %s for %d damage.\n",
607 player->cnum, prship(&vship),
608 xyas(vship.shp_x, vship.shp_y, vict),
611 pr("Shell%s hit %s in %s for %d damage.\n",
612 splur(shots), prsub(&vship),
613 xyas(vship.shp_x, vship.shp_y, player->cnum),
616 if (vship.shp_effic < SHIP_MINEFF)
617 pr("%s sunk!\n", prsub(&vship));
621 /* Ok, now, check if we had a bogus target. If so,
622 just continue on, since there is no defender. */
623 if (target == targ_bogus)
625 if (attacker == targ_unit){
626 attacker = targ_land;
627 getsect(fland.lnd_x,fland.lnd_y,&fsect);
629 totaldefdam=defend(&fired,&defended,target,attacker,&vsect,&fsect,&vship,&fship,fx,fy,&ndefending);
635 putship(vship.shp_uid, &vship);
638 if ((totaldefdam == 0) && (target == targ_ship))
639 if (vship.shp_rflags & RET_INJURED)
640 retreat_ship(&vship,'h');
646 if ((target == targ_ship) || (target == targ_sub)) {
647 if (fship.shp_effic > SHIP_MINEFF) {
648 shp_missdef(&fship, vict);
651 putship(fship.shp_uid, &fship);
658 odds = ((double)ndefending)/((double)nfiring);
661 do_defdam(&fired, odds);
666 defend(struct emp_qelem *al, struct emp_qelem *dl, enum targ_type target, enum targ_type attacker, struct sctstr *vsect, struct sctstr *fsect, struct shpstr *vship, struct shpstr *fship, int fx, int fy, int *nd)
674 if (attacker == targ_land)
675 aown = fsect->sct_own;
677 aown = fship->shp_own;
679 if (target == targ_land)
680 vict = vsect->sct_own;
682 vict = vship->shp_own;
684 if (0 != (dam = quiet_bigdef(attacker,dl,vict,aown,fx,fy,&nfiring))) {
687 fp = (struct flist *)malloc(sizeof(struct flist));
688 bzero((s_char *)fp,sizeof(struct flist));
693 fp->x = fsect->sct_x;
694 fp->y = fsect->sct_y;
695 fp->type = targ_land;
698 fp->type = targ_ship;
699 fp->uid = fship->shp_uid;
702 emp_insque(&fp->queue,al);
709 do_defdam(struct emp_qelem *list, double odds)
712 int dam, vict,first=1;
716 struct emp_qelem *qp, *next;
718 for (qp = list->q_forw; qp != list; qp = next){
720 fp = (struct flist *)qp;
721 if (fp->type == targ_ship) {
722 if (!getship(fp->uid, &ship) ||
728 pr("\nDefenders fire back!\n");
731 dam = (odds * (double)fp->defdam);
733 if (fp->type == targ_ship){
736 "Return fire hit %s in %s for %d damage.\n",
738 xyas(ship.shp_x, ship.shp_y, player->cnum),
742 "Return fire hit %s in %s for %d damage.\n",
744 xyas(ship.shp_x, ship.shp_y, vict),
746 shipdamage(&ship, dam);
747 putship(ship.shp_uid,&ship);
749 getsect(fp->x, fp->y, §);
751 pr("Return fire hit sector %s for %d damage.\n",
752 xyas(fp->x, fp->y, player->cnum), dam);
753 sectdamage(§, dam, 0);
756 wu(0, vict, "Return fire hit sector %s for %d damage.\n",
757 xyas(fp->x, fp->y, vict), dam);
759 emp_remque(&fp->queue);
765 quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown, coord ax, coord ay, int *nfiring)
768 double range, erange, hitchance;
773 int dam, dam2, rel, rel2;
775 struct sctstr firing;
778 double techfact(int, double);
779 extern int torpedo_damage;
785 snxtitem_dist(&ni, EF_SHIP, ax, ay, 8);
786 while (nxtitem(&ni, (caddr_t)&ship)){
787 if (ship.shp_own == 0)
790 if ((mchr[(int)ship.shp_type].m_flags & M_SUB) &&
791 (attacker == targ_land))
794 rel = getrel(getnatp(ship.shp_own),own);
795 rel2 = getrel(getnatp(ship.shp_own),aown);
796 if ((ship.shp_own != own) &&
797 ((rel != ALLIED) || (rel2 != AT_WAR)))
799 /* Don't shoot yourself */
800 if (ship.shp_own == aown)
802 if (ship.shp_effic < 60)
804 if (getvec(VT_ITEM, vec, (caddr_t)&ship, EF_SHIP) < 0)
807 if (vec[I_MILIT] < 1)
810 if (mchr[(int)ship.shp_type].m_flags & M_SUB){
811 if (vec[I_SHELL] < 3)
812 vec[I_SHELL] += supply_commod(ship.shp_own,
813 ship.shp_x,ship.shp_y,I_SHELL,
815 if (vec[I_SHELL] < 3)
820 if (ship.shp_mobil <= 0)
823 erange = ship.shp_effic*
824 techfact(ship.shp_tech,
825 ((double)ship.shp_frnge))
827 erange = (double)roundrange(erange);
828 range = mapdist(ship.shp_x, ship.shp_y, ax, ay);
831 if (!line_of_sight((s_char **)0, ship.shp_x, ship.shp_y, ax, ay))
835 fp = (struct flist *)malloc(sizeof(struct flist));
836 bzero((s_char *)fp,sizeof(struct flist));
837 fp->type = targ_ship;
838 fp->uid = ship.shp_uid;
839 add_to_fired_queue(&fp->queue, list);
841 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
843 hitchance = DTORP_HITCHANCE(range, ship.shp_visib);
844 if (!chance(hitchance))
847 dam += TORP_DAMAGE();
849 range = techfact(ship.shp_tech,
850 ship.shp_frnge * ship.shp_effic / 200.0);
851 range = (double)roundrange(range);
852 if (range < ni.curdist)
854 /* must have gun, shell, and milit to fire */
855 if (vec[I_SHELL] < 1)
856 vec[I_SHELL] += supply_commod(ship.shp_own,
857 ship.shp_x,ship.shp_y,I_SHELL,1);
858 /* only need 1 shell, so don't check that */
859 if (vec[I_SHELL] < 1)
861 nshot = min(vec[I_GUN],vec[I_MILIT]);
862 nshot = min(nshot, ship.shp_glim);
866 fp = (struct flist *)malloc(sizeof(struct flist));
867 bzero((s_char *)fp,sizeof(struct flist));
868 fp->type = targ_ship;
869 fp->uid = ship.shp_uid;
870 add_to_fired_queue(&fp->queue, list);
871 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
872 dam += seagun(ship.shp_effic,nshot);
875 snxtitem_dist(&ni, EF_LAND, ax, ay, 8);
876 while (nxtitem(&ni, (caddr_t)&land)){
877 if (land.lnd_own == 0)
879 if (land.lnd_effic < LAND_MINFIREEFF)
881 /* Can't fire if on a ship */
882 if (land.lnd_ship >= 0)
884 if (land.lnd_land >= 0)
886 /* Gotta have military */
887 if (lnd_getmil(&land) < 1)
889 /* Don't shoot yourself */
890 if (land.lnd_own == aown)
893 rel = getrel(getnatp(land.lnd_own),own);
894 rel2 = getrel(getnatp(land.lnd_own),aown);
896 if ((land.lnd_own != own) &&
897 ((rel != ALLIED) || (rel2 != AT_WAR)))
901 range = techfact((int)land.lnd_tech,
902 (double)land.lnd_frg / 2.0);
903 range = (double)roundrange(range);
904 if (range < ni.curdist)
908 if (!has_supply(&land))
911 if (getvec(VT_ITEM, vec, (caddr_t)&land, EF_LAND) < 0)
914 if (vec[I_MILIT] == 0 || vec[I_SHELL] == 0 || vec[I_GUN] == 0)
917 dam2 = (int)landunitgun(land.lnd_effic, land.lnd_dam, vec[I_GUN],
918 land.lnd_ammo, vec[I_SHELL]);
921 fp = (struct flist *)malloc(sizeof(struct flist));
922 bzero((s_char *)fp,sizeof(struct flist));
923 fp->type = targ_unit;
924 fp->uid = land.lnd_uid;
925 add_to_fired_queue(&fp->queue, list);
927 putland(land.lnd_uid, &land);
928 nreport(land.lnd_own, N_FIRE_BACK, player->cnum, 1);
933 * Determine if any nearby gun-equipped sectors are within
934 * range and able to fire at an attacker. Firing sectors
935 * need to have guns, shells, and military. Sector being
936 * attacked is x,y -- attacker is at ax,ay.
939 if (!opt_NO_FORT_FIRE) {
940 snxtsct_dist(&ns, ax, ay, 8);
941 while (nxtsct(&ns, &firing)){
943 if (firing.sct_type != SCT_FORTR)
945 if (firing.sct_own == 0)
947 rel = getrel(getnatp(firing.sct_own),own);
948 rel2 = getrel(getnatp(firing.sct_own),aown);
950 if ((firing.sct_own != own) &&
951 ((rel != ALLIED) || (rel2 != AT_WAR)))
953 /* Don't shoot yourself */
954 if (firing.sct_own == aown)
956 tech = tfactfire(firing.sct_own, 1.0);
958 if (firing.sct_effic > 59) /* fort bonus */
960 range = (double)roundrange(range);
961 if (range < ns.curdist)
963 if (getvec(VT_ITEM, vec, (caddr_t)&firing, EF_SECTOR) < 0)
965 if (vec[I_SHELL] < 1)
966 vec[I_SHELL] += supply_commod(firing.sct_own,
967 firing.sct_x,firing.sct_y,I_SHELL,1);
968 if (vec[I_GUN] == 0 || vec[I_MILIT] < 5 || vec[I_SHELL] == 0)
971 fp = (struct flist *)malloc(sizeof(struct flist));
972 bzero((s_char *)fp,sizeof(struct flist));
973 fp->x = firing.sct_x;
974 fp->y = firing.sct_y;
975 fp->type = targ_land;
976 add_to_fired_queue(&fp->queue, list);
977 nreport(firing.sct_own, N_FIRE_BACK, player->cnum, 1);
981 dam += landgun((int)firing.sct_effic,gun);
985 return ((*nfiring) == 0 ? 0 : (dam/(*nfiring)));
989 use_ammo(struct emp_qelem *list)
991 struct emp_qelem *qp, *next;
1001 /* use 1 shell from everyone */
1002 for (qp = list->q_forw; qp != list; qp = next){
1004 fp = (struct flist *)qp;
1005 if (fp->type == targ_ship){
1006 getship(fp->uid,&ship);
1007 ptr = (s_char *)&ship;
1009 if (mchr[(int)ship.shp_type].m_flags & M_SUB){
1010 shell = getvar(V_SHELL, ptr, type);
1014 putvar(V_SHELL, shell, ptr, type);
1015 putship(ship.shp_uid, &ship);
1016 mcp = &mchr[(int)ship.shp_type];
1017 mobcost = ship.shp_effic * 0.01 * ship.shp_speed;
1018 mobcost = (480.0 / (mobcost +
1019 techfact(ship.shp_tech, mobcost)));
1020 /* mob cost = 1/2 a sect's mob */
1022 ship.shp_mobil -= mobcost;
1024 }else if (fp->type == targ_land){
1025 getsect(fp->x,fp->y,§);
1026 ptr = (s_char *)§
1029 getland(fp->uid,&land);
1030 ptr = (s_char *)&land;
1033 shell = getvar(V_SHELL, ptr, type);
1037 putvar(V_SHELL, shell, ptr, type);
1038 if (fp->type == targ_ship)
1039 putship(ship.shp_uid,&ship);
1040 else if (fp->type == targ_land)
1043 putland(land.lnd_uid,&land);
1045 emp_remque(&fp->queue);
1052 add_to_fired_queue(struct emp_qelem *elem, struct emp_qelem *list)
1054 struct emp_qelem *qp;
1055 struct flist *fp, *ep;
1058 ep = (struct flist *)elem;
1060 /* Don't put them on the list if they're already there */
1061 for (qp = list->q_forw; qp != list; qp = qp->q_forw){
1062 fp = (struct flist *)qp;
1063 if ((fp->type == targ_ship) && (fp->uid == ep->uid))
1065 if ((fp->type != targ_ship) && (fp->x == ep->x) &&
1071 emp_insque(elem, list);