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,
81 struct shpstr *fship, int fx, int fy, int *nd);
110 enum targ_type target, attacker, orig_attacker;
113 struct nstr_item nbst;
119 struct emp_qelem fired, defended;
127 emp_initque(&defended);
129 while ((type != EF_SECTOR) && (type != EF_SHIP) && (type != EF_LAND)) {
130 if (!(p = getstarg(player->argp[1],
131 "Firing from ship(s), sect(s), or land unit(s)? ",
136 if (type == EF_SECTOR) {
137 if (opt_NO_FORT_FIRE) {
138 pr("Fort firing is disabled.\n");
141 orig_attacker = attacker = targ_land;
143 } else if (type == EF_SHIP) {
144 orig_attacker = attacker = targ_ship;
145 } else if (type == EF_LAND) {
146 orig_attacker = attacker = targ_unit;
148 pr("Please type 'sh', 'l', or 'se'!\n");
150 if ((ptr = getstarg(player->argp[2], "Firing from? ", buf)) == 0
154 if (!snxtitem(&nbst, type, ptr))
157 if (player->aborted) {
158 pr("Fire aborted.\n");
161 while (nxtitem(&nbst, (s_char *)&item)) {
162 attacker = orig_attacker;
163 if (attacker == targ_unit) {
164 if (!getland(item.land.lnd_uid, &fland))
166 if (!getsect(item.land.lnd_x, item.land.lnd_y, &fsect))
168 if (item.land.lnd_own != player->cnum)
171 if (fland.lnd_frg == 0) {
172 pr("Unit %d cannot fire!\n", fland.lnd_uid);
175 if (lnd_getmil(&fland) < 1) {
176 pr("Unit %d cannot fire because it has no military!\n",
180 if (fland.lnd_ship >= 0) {
181 pr("Unit %d cannot fire because it is on a ship!\n",
185 if (fland.lnd_land >= 0) {
186 pr("Unit %d cannot fire because it is on a land unit!\n",
190 if (fland.lnd_effic < LAND_MINFIREEFF) {
191 pr("Unit %d cannot fire because it is less than %d%% efficient\n", fland.lnd_uid, LAND_MINFIREEFF);
194 resupply_commod(&fland, I_SHELL); /* Get more shells */
195 putland(fland.lnd_uid, &fland);
196 if (getvar(V_SHELL, (s_char *)&fland, EF_LAND) == 0) {
197 pr("%s -- not enough shells\n", prland(&fland));
200 } else if (attacker == targ_ship) {
201 if (!getship(item.ship.shp_uid, &fship))
203 if (item.ship.shp_own != player->cnum)
205 if (getvar(V_MILIT, (s_char *)&item.ship, EF_SHIP) < 1) {
206 pr("Not enough mil on ship #%d\n", item.ship.shp_uid);
209 gun = getvar(V_GUN, (s_char *)&item.ship, EF_SHIP);
210 gun = min(gun, item.ship.shp_glim);
211 if (item.ship.shp_frnge == 0) {
212 pr("Ships %d cannot fire guns!\n", item.ship.shp_uid);
216 pr("Not enough guns on ship #%d\n", item.ship.shp_uid);
219 if (getvar(V_SHELL, (s_char *)&item.ship, EF_SHIP) == 0) {
220 pr("Not enough shells on ship #%d\n", item.ship.shp_uid);
223 if (item.ship.shp_effic < 60) {
224 pr("Ship #%d is crippled!\n", item.ship.shp_uid);
227 fshipno = fship.shp_uid;
228 } else if (attacker == targ_land) {
229 if (!getsect(item.sect.sct_x, item.sect.sct_y, &fsect))
231 if (item.sect.sct_own != player->cnum)
233 if (item.sect.sct_type != SCT_FORTR)
235 if (item.sect.sct_effic < ((u_char)FORTEFF)) {
236 pr("Fort not efficient enough to fire!\n");
239 if (getvar(V_GUN, (s_char *)&item.sect, EF_SECTOR) == 0) {
240 pr("Not enough guns in sector %s!\n",
241 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
244 if (getvar(V_SHELL, (s_char *)&item.sect, EF_SECTOR) == 0) {
245 pr("Not enough shells in sector %s!\n",
246 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
249 if (getvar(V_MILIT, (s_char *)&item.sect, EF_SECTOR) < 5) {
250 pr("Not enough military in sector %s!\n",
251 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
254 pr("\nSector %s firing\n",
255 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
257 if ((ptr = getstarg(player->argp[3], "Firing at? ", buf)) == 0
260 if (player->aborted) {
261 pr("Fire aborted.\n");
265 (void)strcpy(vbuf, ptr);
270 if (target == targ_ship) {
271 vshipno = atoi(vbuf);
272 if (vshipno < 0 || !getship(vshipno, &vship) ||
274 pr("No such ship exists!\n");
277 target = (mchr[(int)vship.shp_type].m_flags & M_SUB) ?
278 targ_sub : targ_ship;
279 vict = vship.shp_own;
282 if (!getsect(x, y, &vsect)) {
283 pr("No such sector exists!\n");
287 if (!sarg_xy(vbuf, &x, &y) || !getsect(x, y, &vsect)) {
288 pr("No such sector exists!\n");
291 /* We check the sector type, but we only use it for damage, not
292 reporting. That way, you don't get extra information you wouldn't
293 normally get. Besides, what if they want to slam water? :) */
294 if (vsect.sct_type == SCT_SANCT || vsect.sct_type == SCT_WATER)
298 vict = vsect.sct_own;
302 if (attacker == targ_ship) {
303 shots = -1; /* convert to max later */
304 if (fship.shp_own != player->cnum) {
305 pr("Not your ship!\n");
308 if (target == targ_sub || target == targ_ship) {
309 if (fship.shp_uid == vship.shp_uid) {
310 pr("You can't fire upon yourself!\n");
317 attacker = (mchr[fship.shp_type].m_flags & M_SUB) ?
318 targ_sub : targ_ship;
319 if (attacker == targ_sub){
320 pr("Subs may not fire normally.. use torpedo.\n");
324 attacker = targ_ship;
325 if ((mil = getvar(V_MILIT, (s_char *)&fship, EF_SHIP)) < 1) {
326 pr("Not enough military for firing crew.\n");
329 gun = getvar(V_GUN, (s_char *)&fship, EF_SHIP);
330 gun = min(gun, fship.shp_glim);
331 if (fship.shp_frnge == 0 || gun == 0) {
332 pr("Insufficient arms.\n");
335 shell = getvar(V_SHELL, (s_char *)&fship, EF_SHIP);
337 shell += supply_commod(fship.shp_own, fship.shp_x,
338 fship.shp_y, I_SHELL, 2 - shell);
343 if (fship.shp_effic < 60) {
344 pr("Ship #%d is crippled (%d%%)\n", fshipno,
348 range = techfact(fship.shp_tech,
349 (double)fship.shp_frnge / 2.0);
350 range2 = (double)roundrange(range);
351 pr("range is %.2f (%.2f)\n", range2, range);
352 if (target == targ_sub) {
353 if ((mchr[(int)fship.shp_type].m_flags & M_DCH) == 0) {
354 pr("A %s can't drop depth charges!\n",
355 mchr[(int)fship.shp_type].m_name);
359 pr("Not enough shells for depth charge!\n");
363 gun = min(gun, shell * 2);
364 gun = min(gun, mil / 2);
366 if (shots > gun || shots < 0)
368 else if (shots == 0) {
369 pr("No shots fired.\n");
372 guneff = seagun(fship.shp_effic, shots);
374 shell -= ldround(((double)shots) / 2.0, 1);
375 putvar(V_SHELL, shell, (s_char *)&fship, EF_SHIP);
376 putship(fship.shp_uid, &fship);
377 if (opt_NOMOBCOST == 0)
378 fship.shp_mobil = max(fship.shp_mobil - 15, -100);
379 } else if (attacker == targ_unit) {
380 if (fland.lnd_own != player->cnum) {
381 pr("Not your unit!\n");
385 if (target == targ_land) {
386 if (fland.lnd_x == vsect.sct_x
387 && fland.lnd_y == vsect.sct_y) {
388 pr("You can't fire upon yourself!\n");
396 if (fland.lnd_frg == 0) {
397 pr("Unit %d cannot fire!\n", fland.lnd_uid);
400 if (getvar(V_SHELL, (s_char *)&fland, EF_LAND) == 0) {
401 pr("%s -- not enough shells\n", prland(&fland));
405 shell = getvar(V_SHELL, (s_char *)&fland, EF_LAND);
407 range = techfact((int)fland.lnd_tech,
408 (double)fland.lnd_frg / 2.0);
409 range2 = (double)roundrange(range);
410 pr("range is %.2f (%.2f)\n", range2, range);
411 if (target == targ_sub) {
412 pr("A %s can't drop depth charges!\n",
413 lchr[(int)fland.lnd_type].l_name);
417 gun = getvar(V_GUN, (s_char *)&fland, EF_LAND);
419 pr("%s -- not enough guns\n", prland(&fland));
423 dam = (int)landunitgun(fland.lnd_effic, fland.lnd_dam, gun,
424 fland.lnd_ammo, shell);
425 if (target == targ_ship) {
426 if (chance(((double)fland.lnd_acc) / 100.0))
427 dam = ldround(((double)dam / 2.0), 1);
430 resupply_commod(&fland, I_SHELL); /* Get more shells */
431 putland(fland.lnd_uid, &fland);
435 if (fsect.sct_own != player->cnum ||
436 fsect.sct_type != SCT_FORTR) {
437 pr("No fortress at %s\n", xyas(fsect.sct_x,
438 fsect.sct_y, player->cnum));
441 if (target == targ_land) {
442 if (fsect.sct_x == vsect.sct_x
443 && fsect.sct_y == vsect.sct_y) {
444 pr("You can't fire upon yourself!\n");
448 attacker = targ_land;
449 if ((gun = getvar(V_GUN, (s_char *)&fsect, EF_SECTOR)) == 0) {
450 pr("Insufficient arms.\n");
453 shell = getvar(V_SHELL, (s_char *)&fsect, EF_SECTOR);
455 shell += supply_commod(fsect.sct_own, fsect.sct_x,
456 fsect.sct_y, I_SHELL, 1);
461 if (getvar(V_MILIT, (s_char *)&fsect, EF_SECTOR) < 5) {
462 pr("Not enough military for firing crew.\n");
465 if (target == targ_sub) {
466 pr("Target ship not sighted!\n");
471 range = tfactfire(player->cnum, 7.0);
472 if (fsect.sct_effic > 59)
474 range2 = (double)roundrange(range);
475 pr("range is %.2f (%.2f)\n", range2, range);
476 guneff = landgun((int)fsect.sct_effic, gun);
479 putvar(V_SHELL, shell, (s_char *)&fsect, EF_SECTOR);
482 trange = mapdist(x, y, fx, fy);
483 if (trange > range2) {
484 pr("Target out of range.\n");
489 pr("Target out of range. Thud.\n");
492 pr("Target ship out of range. Splash.\n");
501 fland.lnd_mission = 0;
502 putland(fland.lnd_uid, &fland);
505 fship.shp_mission = 0;
506 putship(fship.shp_uid, &fship);
511 if (target == targ_bogus) {
512 if (vsect.sct_type == SCT_SANCT) {
513 pr("%s is a %s!!\n", vbuf,
514 dchr[SCT_SANCT].d_name);
516 } else if (vsect.sct_type == SCT_WATER) {
517 pr("You must specify a ship in sector %s!\n",
525 if (!trechk(player->cnum, vict, SEAFIR))
529 if (!trechk(player->cnum, vict, SUBFIR))
534 if (!trechk(player->cnum, vict, LANFIR))
542 if (target == targ_land) {
543 natp = getnatp(player->cnum);
544 rel = getrel(natp, vict);
545 if ((rel != AT_WAR) && (player->cnum != vict) &&
546 (vict) && (vsect.sct_oldown != player->cnum)) {
547 pr("You're not at war with them!\n");
557 if (vship.shp_rflags & RET_DCHRGED)
558 retreat_ship(&vship, 'd');
563 prb = (double)(range2 ? (trange / range2) : 1.0);
572 pr("Wind deflects shell%s.\n", splur(shots));
573 /* dam = (int)((double)dam / 2.0);*/
576 (double)((double)(90 - (random() % 11)) /
586 nreport(player->cnum, N_SCT_SHELL, vict, 1);
587 if (vict && vict != player->cnum)
589 "Country #%d shelled sector %s for %d damage.\n",
590 player->cnum, xyas(x, y, vict), dam);
591 pr("Shell%s hit sector %s for %d damage.\n",
592 splur(shots), xyas(x, y, player->cnum), dam);
593 /* Ok, it wasn't a bogus target, so do damage. */
594 if (target != targ_bogus)
595 sectdamage(&vsect, dam, 0);
598 nreport(player->cnum, N_SHP_SHELL, vict, 1);
600 if ((target != targ_sub) ||
601 ((vship.shp_rflags & RET_DCHRGED) == 0))
602 check_retreat_and_do_shipdamage(&vship, dam);
604 shipdamage(&vship, dam);
607 "Country #%d shelled %s in %s for %d damage.\n",
608 player->cnum, prship(&vship),
609 xyas(vship.shp_x, vship.shp_y, vict), dam);
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), dam);
615 if (vship.shp_effic < SHIP_MINEFF)
616 pr("%s sunk!\n", prsub(&vship));
620 /* Ok, now, check if we had a bogus target. If so,
621 just continue on, since there is no defender. */
622 if (target == targ_bogus)
624 if (attacker == targ_unit) {
625 attacker = targ_land;
626 getsect(fland.lnd_x, fland.lnd_y, &fsect);
629 defend(&fired, &defended, target, attacker, &vsect, &fsect,
630 &vship, &fship, fx, fy, &ndefending);
636 putship(vship.shp_uid, &vship);
639 if ((totaldefdam == 0) && (target == targ_ship))
640 if (vship.shp_rflags & RET_INJURED)
641 retreat_ship(&vship, 'h');
647 if ((target == targ_ship) || (target == targ_sub)) {
648 if (fship.shp_effic > SHIP_MINEFF) {
649 shp_missdef(&fship, vict);
652 putship(fship.shp_uid, &fship);
659 odds = ((double)ndefending) / ((double)nfiring);
662 do_defdam(&fired, odds);
667 defend(struct emp_qelem *al, struct emp_qelem *dl, enum targ_type target,
668 enum targ_type attacker, struct sctstr *vsect, struct sctstr *fsect,
669 struct shpstr *vship, struct shpstr *fship, int fx, int fy, int *nd)
673 int vict, nfiring = 0;
677 if (attacker == targ_land)
678 aown = fsect->sct_own;
680 aown = fship->shp_own;
682 if (target == targ_land)
683 vict = vsect->sct_own;
685 vict = vship->shp_own;
688 (dam = quiet_bigdef(attacker, dl, vict, aown, fx, fy, &nfiring))) {
691 fp = (struct flist *)malloc(sizeof(struct flist));
692 bzero((s_char *)fp, sizeof(struct flist));
697 fp->x = fsect->sct_x;
698 fp->y = fsect->sct_y;
699 fp->type = targ_land;
702 fp->type = targ_ship;
703 fp->uid = fship->shp_uid;
706 emp_insque(&fp->queue, al);
713 do_defdam(struct emp_qelem *list, double odds)
716 int dam, vict, first = 1;
720 struct emp_qelem *qp, *next;
722 for (qp = list->q_forw; qp != list; qp = next) {
724 fp = (struct flist *)qp;
725 if (fp->type == targ_ship) {
726 if (!getship(fp->uid, &ship) || !ship.shp_own)
731 pr("\nDefenders fire back!\n");
734 dam = (odds * (double)fp->defdam);
736 if (fp->type == targ_ship) {
738 pr("Return fire hit %s in %s for %d damage.\n",
740 xyas(ship.shp_x, ship.shp_y, player->cnum), dam);
743 "Return fire hit %s in %s for %d damage.\n",
744 prsub(&ship), xyas(ship.shp_x, ship.shp_y, vict), dam);
745 shipdamage(&ship, dam);
746 putship(ship.shp_uid, &ship);
748 getsect(fp->x, fp->y, §);
750 pr("Return fire hit sector %s for %d damage.\n",
751 xyas(fp->x, fp->y, player->cnum), dam);
752 sectdamage(§, dam, 0);
755 wu(0, vict, "Return fire hit sector %s for %d damage.\n",
756 xyas(fp->x, fp->y, vict), dam);
758 emp_remque(&fp->queue);
764 quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown,
765 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) && ((rel != ALLIED) || (rel2 != AT_WAR)))
798 /* Don't shoot yourself */
799 if (ship.shp_own == aown)
801 if (ship.shp_effic < 60)
803 if (getvec(VT_ITEM, vec, (caddr_t)&ship, EF_SHIP) < 0)
806 if (vec[I_MILIT] < 1)
809 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
810 if (vec[I_SHELL] < 3)
811 vec[I_SHELL] += supply_commod(ship.shp_own,
812 ship.shp_x, ship.shp_y,
813 I_SHELL, 3 - vec[I_SHELL]);
814 if (vec[I_SHELL] < 3)
819 if (ship.shp_mobil <= 0)
822 erange = ship.shp_effic *
823 techfact(ship.shp_tech, ((double)ship.shp_frnge))
825 erange = (double)roundrange(erange);
826 range = mapdist(ship.shp_x, ship.shp_y, ax, ay);
830 ((s_char **)0, ship.shp_x, ship.shp_y, ax, ay))
834 fp = (struct flist *)malloc(sizeof(struct flist));
835 bzero((s_char *)fp, sizeof(struct flist));
836 fp->type = targ_ship;
837 fp->uid = ship.shp_uid;
838 add_to_fired_queue(&fp->queue, list);
840 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
842 hitchance = DTORP_HITCHANCE(range, ship.shp_visib);
843 if (!chance(hitchance))
846 dam += TORP_DAMAGE();
848 range = techfact(ship.shp_tech,
849 ship.shp_frnge * ship.shp_effic / 200.0);
850 range = (double)roundrange(range);
851 if (range < ni.curdist)
853 /* must have gun, shell, and milit to fire */
854 if (vec[I_SHELL] < 1)
855 vec[I_SHELL] += supply_commod(ship.shp_own,
856 ship.shp_x, ship.shp_y,
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) && ((rel != ALLIED) || (rel2 != AT_WAR)))
900 range = techfact((int)land.lnd_tech, (double)land.lnd_frg / 2.0);
901 range = (double)roundrange(range);
902 if (range < ni.curdist)
906 if (!has_supply(&land))
909 if (getvec(VT_ITEM, vec, (caddr_t)&land, EF_LAND) < 0)
912 if (vec[I_MILIT] == 0 || vec[I_SHELL] == 0 || vec[I_GUN] == 0)
915 dam2 = (int)landunitgun(land.lnd_effic, land.lnd_dam, vec[I_GUN],
916 land.lnd_ammo, vec[I_SHELL]);
919 fp = (struct flist *)malloc(sizeof(struct flist));
920 bzero((s_char *)fp, sizeof(struct flist));
921 fp->type = targ_unit;
922 fp->uid = land.lnd_uid;
923 add_to_fired_queue(&fp->queue, list);
925 putland(land.lnd_uid, &land);
926 nreport(land.lnd_own, N_FIRE_BACK, player->cnum, 1);
931 * Determine if any nearby gun-equipped sectors are within
932 * range and able to fire at an attacker. Firing sectors
933 * need to have guns, shells, and military. Sector being
934 * attacked is x,y -- attacker is at ax,ay.
937 if (!opt_NO_FORT_FIRE) {
938 snxtsct_dist(&ns, ax, ay, 8);
939 while (nxtsct(&ns, &firing)) {
941 if (firing.sct_type != SCT_FORTR)
943 if (firing.sct_own == 0)
945 rel = getrel(getnatp(firing.sct_own), own);
946 rel2 = getrel(getnatp(firing.sct_own), aown);
948 if ((firing.sct_own != own) &&
949 ((rel != ALLIED) || (rel2 != AT_WAR)))
951 /* Don't shoot yourself */
952 if (firing.sct_own == aown)
954 tech = tfactfire(firing.sct_own, 1.0);
956 if (firing.sct_effic > 59) /* fort bonus */
958 range = (double)roundrange(range);
959 if (range < ns.curdist)
961 if (getvec(VT_ITEM, vec, (caddr_t)&firing, EF_SECTOR) < 0)
963 if (vec[I_SHELL] < 1)
964 vec[I_SHELL] += supply_commod(firing.sct_own,
965 firing.sct_x, firing.sct_y,
967 if (vec[I_GUN] == 0 || vec[I_MILIT] < 5 || vec[I_SHELL] == 0)
970 fp = (struct flist *)malloc(sizeof(struct flist));
971 bzero((s_char *)fp, sizeof(struct flist));
972 fp->x = firing.sct_x;
973 fp->y = firing.sct_y;
974 fp->type = targ_land;
975 add_to_fired_queue(&fp->queue, list);
976 nreport(firing.sct_own, N_FIRE_BACK, player->cnum, 1);
980 dam += landgun((int)firing.sct_effic, gun);
984 return ((*nfiring) == 0 ? 0 : (dam / (*nfiring)));
988 use_ammo(struct emp_qelem *list)
990 struct emp_qelem *qp, *next;
1000 /* use 1 shell from everyone */
1001 for (qp = list->q_forw; qp != list; qp = next) {
1003 fp = (struct flist *)qp;
1004 if (fp->type == targ_ship) {
1005 getship(fp->uid, &ship);
1006 ptr = (s_char *)&ship;
1008 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
1009 shell = getvar(V_SHELL, ptr, type);
1013 putvar(V_SHELL, shell, ptr, type);
1014 putship(ship.shp_uid, &ship);
1015 mcp = &mchr[(int)ship.shp_type];
1016 mobcost = ship.shp_effic * 0.01 * ship.shp_speed;
1017 mobcost = (480.0 / (mobcost +
1018 techfact(ship.shp_tech, mobcost)));
1019 /* mob cost = 1/2 a sect's mob */
1021 ship.shp_mobil -= mobcost;
1023 } else if (fp->type == targ_land) {
1024 getsect(fp->x, fp->y, §);
1025 ptr = (s_char *)§
1028 getland(fp->uid, &land);
1029 ptr = (s_char *)&land;
1032 shell = getvar(V_SHELL, ptr, type);
1036 putvar(V_SHELL, shell, ptr, type);
1037 if (fp->type == targ_ship)
1038 putship(ship.shp_uid, &ship);
1039 else if (fp->type == targ_land)
1042 putland(land.lnd_uid, &land);
1044 emp_remque(&fp->queue);
1051 add_to_fired_queue(struct emp_qelem *elem, struct emp_qelem *list)
1053 struct emp_qelem *qp;
1054 struct flist *fp, *ep;
1057 ep = (struct flist *)elem;
1059 /* Don't put them on the list if they're already there */
1060 for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
1061 fp = (struct flist *)qp;
1062 if ((fp->type == targ_ship) && (fp->uid == ep->uid))
1064 if ((fp->type != targ_ship) && (fp->x == ep->x) &&
1070 emp_insque(elem, list);