2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2004, 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:
54 targ_land, targ_ship, targ_sub, targ_unit, targ_bogus
58 struct emp_qelem queue; /* list of fired things */
59 int type; /* ship? otherwise sector */
60 int uid; /* ship uid */
61 coord x, y; /* sector coords */
62 int defdam; /* damage defenders did */
63 int victim; /* who I was shooting at */
72 static void add_to_fired_queue(struct emp_qelem *, struct emp_qelem *);
73 static int defend(struct emp_qelem *al,
75 enum targ_type target,
76 enum targ_type attacker,
80 struct shpstr *fship, int fx, int fy, int *nd);
81 static void do_defdam(struct emp_qelem *, double);
82 static int quiet_bigdef(int, struct emp_qelem *, natid, natid, coord,
84 static void use_ammo(struct emp_qelem *);
113 enum targ_type target, attacker, orig_attacker;
116 struct nstr_item nbst;
122 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 (fland.lnd_item[I_SHELL] == 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 (item.ship.shp_item[I_MILIT] < 1) {
206 pr("Not enough mil on ship #%d\n", item.ship.shp_uid);
209 gun = item.ship.shp_item[I_GUN];
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 (item.ship.shp_item[I_SHELL] == 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 (item.sect.sct_item[I_GUN] == 0) {
240 pr("Not enough guns in sector %s!\n",
241 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
244 if (item.sect.sct_item[I_SHELL] == 0) {
245 pr("Not enough shells in sector %s!\n",
246 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
249 if (item.sect.sct_item[I_MILIT] < 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 if (fship.shp_own != player->cnum) {
304 pr("Not your ship!\n");
307 if (target == targ_sub || target == targ_ship) {
308 if (fship.shp_uid == vship.shp_uid) {
309 pr("You can't fire upon yourself!\n");
316 attacker = (mchr[fship.shp_type].m_flags & M_SUB) ?
317 targ_sub : targ_ship;
318 if (attacker == targ_sub){
319 pr("Subs may not fire normally.. use torpedo.\n");
323 attacker = targ_ship;
324 if ((mil = fship.shp_item[I_MILIT]) < 1) {
325 pr("Not enough military for firing crew.\n");
328 gun = fship.shp_item[I_GUN];
329 gun = min(gun, fship.shp_glim);
330 if (fship.shp_frnge == 0 || gun == 0) {
331 pr("Insufficient arms.\n");
334 shell = fship.shp_item[I_SHELL];
336 shell += supply_commod(fship.shp_own, fship.shp_x,
337 fship.shp_y, I_SHELL, 2 - shell);
342 if (fship.shp_effic < 60) {
343 pr("Ship #%d is crippled (%d%%)\n", fshipno,
347 range = techfact(fship.shp_tech,
348 (double)fship.shp_frnge / 2.0);
349 range2 = (double)roundrange(range);
350 pr("range is %.2f (%.2f)\n", range2, range);
351 if (target == targ_sub) {
352 if ((mchr[(int)fship.shp_type].m_flags & M_DCH) == 0) {
353 /* Don't tell it's a sub */
355 } else if (shell < 2) {
356 pr("Not enough shells for depth charge!\n");
360 gun = min(gun, shell * 2);
361 gun = min(gun, mil / 2);
364 guneff = seagun(fship.shp_effic, shots);
366 shell -= ldround(((double)shots) / 2.0, 1);
367 fship.shp_item[I_SHELL] = shell;
368 if (opt_NOMOBCOST == 0)
369 fship.shp_mobil = max(fship.shp_mobil - 15, -100);
370 putship(fship.shp_uid, &fship);
371 } else if (attacker == targ_unit) {
372 if (fland.lnd_own != player->cnum) {
373 pr("Not your unit!\n");
377 if (target == targ_land) {
378 if (fland.lnd_x == vsect.sct_x
379 && fland.lnd_y == vsect.sct_y) {
380 pr("You can't fire upon yourself!\n");
388 if (fland.lnd_frg == 0) {
389 pr("Unit %d cannot fire!\n", fland.lnd_uid);
392 if (fland.lnd_item[I_SHELL] == 0) {
393 pr("%s -- not enough shells\n", prland(&fland));
397 shell = fland.lnd_item[I_SHELL];
399 range = techfact((int)fland.lnd_tech,
400 (double)fland.lnd_frg / 2.0);
401 range2 = (double)roundrange(range);
402 pr("range is %.2f (%.2f)\n", range2, range);
403 if (target == targ_sub) {
404 /* Don't tell it's a sub */
408 gun = fland.lnd_item[I_GUN];
410 pr("%s -- not enough guns\n", prland(&fland));
414 dam = (int)landunitgun(fland.lnd_effic, fland.lnd_dam, gun,
415 fland.lnd_ammo, shell);
416 if (target == targ_ship) {
417 if (chance(((double)fland.lnd_acc) / 100.0))
418 dam = ldround(((double)dam / 2.0), 1);
421 resupply_commod(&fland, I_SHELL); /* Get more shells */
422 putland(fland.lnd_uid, &fland);
426 if (fsect.sct_own != player->cnum ||
427 fsect.sct_type != SCT_FORTR) {
428 pr("No fortress at %s\n", xyas(fsect.sct_x,
429 fsect.sct_y, player->cnum));
432 if (target == targ_land) {
433 if (fsect.sct_x == vsect.sct_x
434 && fsect.sct_y == vsect.sct_y) {
435 pr("You can't fire upon yourself!\n");
439 attacker = targ_land;
440 if ((gun = fsect.sct_item[I_GUN]) == 0) {
441 pr("Insufficient arms.\n");
444 shell = fsect.sct_item[I_SHELL];
446 shell += supply_commod(fsect.sct_own, fsect.sct_x,
447 fsect.sct_y, I_SHELL, 1);
452 if (fsect.sct_item[I_MILIT] < 5) {
453 pr("Not enough military for firing crew.\n");
458 range = tfactfire(player->cnum, 7.0);
459 if (fsect.sct_effic > 59)
461 range2 = (double)roundrange(range);
462 pr("range is %.2f (%.2f)\n", range2, range);
463 if (target == targ_sub) {
464 /* Don't tell it's a sub */
467 guneff = landgun((int)fsect.sct_effic, gun);
470 fsect.sct_item[I_SHELL] = shell;
473 trange = mapdist(x, y, fx, fy);
474 if (trange > range2) {
475 pr("Target out of range.\n");
480 pr("Target out of range. Thud.\n");
483 pr("Target ship out of range. Splash.\n");
492 fland.lnd_mission = 0;
493 putland(fland.lnd_uid, &fland);
496 fship.shp_mission = 0;
497 putship(fship.shp_uid, &fship);
502 if (target == targ_bogus) {
503 if (vsect.sct_type == SCT_SANCT) {
504 pr("%s is a %s!!\n", vbuf,
505 dchr[SCT_SANCT].d_name);
507 } else if (vsect.sct_type == SCT_WATER) {
508 pr("You must specify a ship in sector %s!\n",
516 if (!trechk(player->cnum, vict, SEAFIR))
520 if (!trechk(player->cnum, vict, SUBFIR))
525 if (!trechk(player->cnum, vict, LANFIR))
533 if (target == targ_land) {
534 natp = getnatp(player->cnum);
535 rel = getrel(natp, vict);
536 if ((rel != AT_WAR) && (player->cnum != vict) &&
537 (vict) && (vsect.sct_oldown != player->cnum)) {
538 pr("You're not at war with them!\n");
548 if (vship.shp_rflags & RET_DCHRGED)
549 retreat_ship(&vship, 'd');
554 prb = (double)(range2 ? (trange / range2) : 1.0);
558 pr("Wind deflects shell%s.\n", splur(shots));
559 /* dam = (int)((double)dam / 2.0);*/
562 (double)((double)(90 - (random() % 11)) /
572 nreport(player->cnum, N_SCT_SHELL, vict, 1);
573 if (vict && vict != player->cnum)
575 "Country #%d shelled sector %s for %d damage.\n",
576 player->cnum, xyas(x, y, vict), dam);
577 pr("Shell%s hit sector %s for %d damage.\n",
578 splur(shots), xyas(x, y, player->cnum), dam);
579 /* Ok, it wasn't a bogus target, so do damage. */
580 if (target != targ_bogus)
581 sectdamage(&vsect, dam, 0);
584 nreport(player->cnum, N_SHP_SHELL, vict, 1);
587 if ((target != targ_sub) ||
588 ((vship.shp_rflags & RET_DCHRGED) == 0))
589 check_retreat_and_do_shipdamage(&vship, dam);
591 shipdamage(&vship, dam);
594 "Country #%d shelled %s in %s for %d damage.\n",
595 player->cnum, prship(&vship),
596 xyas(vship.shp_x, vship.shp_y, vict), dam);
598 pr("Shell%s hit %s in %s for %d damage.\n",
599 splur(shots), prsub(&vship),
600 xyas(vship.shp_x, vship.shp_y, player->cnum), dam);
602 if (vship.shp_effic < SHIP_MINEFF)
603 pr("%s sunk!\n", prsub(&vship));
607 /* Ok, now, check if we had a bogus target. If so,
608 just continue on, since there is no defender. */
609 if (target == targ_bogus)
611 if (attacker == targ_unit) {
612 attacker = targ_land;
613 getsect(fland.lnd_x, fland.lnd_y, &fsect);
616 defend(&fired, &defended, target, attacker, &vsect, &fsect,
617 &vship, &fship, fx, fy, &ndefending);
623 putship(vship.shp_uid, &vship);
626 if ((totaldefdam == 0) && (target == targ_ship))
627 if (vship.shp_rflags & RET_INJURED)
628 retreat_ship(&vship, 'h');
634 if ((target == targ_ship) || (target == targ_sub)) {
635 if (fship.shp_effic > SHIP_MINEFF) {
636 shp_missdef(&fship, vict);
639 putship(fship.shp_uid, &fship);
646 odds = ((double)ndefending) / ((double)nfiring);
649 do_defdam(&fired, odds);
654 defend(struct emp_qelem *al, struct emp_qelem *dl, enum targ_type target,
655 enum targ_type attacker, struct sctstr *vsect, struct sctstr *fsect,
656 struct shpstr *vship, struct shpstr *fship, int fx, int fy, int *nd)
660 int vict, nfiring = 0;
664 if (attacker == targ_land)
665 aown = fsect->sct_own;
667 aown = fship->shp_own;
669 if (target == targ_land)
670 vict = vsect->sct_own;
672 vict = vship->shp_own;
675 (dam = quiet_bigdef(attacker, dl, vict, aown, fx, fy, &nfiring))) {
678 fp = (struct flist *)malloc(sizeof(struct flist));
679 memset(fp, 0, sizeof(struct flist));
684 fp->x = fsect->sct_x;
685 fp->y = fsect->sct_y;
686 fp->type = targ_land;
689 fp->type = targ_ship;
690 fp->uid = fship->shp_uid;
693 emp_insque(&fp->queue, al);
700 do_defdam(struct emp_qelem *list, double odds)
703 int dam, vict, first = 1;
707 struct emp_qelem *qp, *next;
709 for (qp = list->q_forw; qp != list; qp = next) {
711 fp = (struct flist *)qp;
712 if (fp->type == targ_ship) {
713 if (!getship(fp->uid, &ship) || !ship.shp_own)
718 pr("\nDefenders fire back!\n");
721 dam = (odds * (double)fp->defdam);
723 if (fp->type == targ_ship) {
725 pr("Return fire hit %s in %s for %d damage.\n",
727 xyas(ship.shp_x, ship.shp_y, player->cnum), dam);
730 "Return fire hit %s in %s for %d damage.\n",
731 prsub(&ship), xyas(ship.shp_x, ship.shp_y, vict), dam);
732 shipdamage(&ship, dam);
733 putship(ship.shp_uid, &ship);
735 getsect(fp->x, fp->y, §);
737 pr("Return fire hit sector %s for %d damage.\n",
738 xyas(fp->x, fp->y, player->cnum), dam);
739 sectdamage(§, dam, 0);
742 wu(0, vict, "Return fire hit sector %s for %d damage.\n",
743 xyas(fp->x, fp->y, vict), dam);
745 emp_remque(&fp->queue);
751 quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown,
752 coord ax, coord ay, int *nfiring)
755 double range, erange, hitchance;
759 int dam, dam2, rel, rel2;
761 struct sctstr firing;
769 snxtitem_dist(&ni, EF_SHIP, ax, ay, 8);
770 while (nxtitem(&ni, &ship)) {
771 if (ship.shp_own == 0)
774 if ((mchr[(int)ship.shp_type].m_flags & M_SUB) &&
775 (attacker == targ_land))
778 rel = getrel(getnatp(ship.shp_own), own);
779 rel2 = getrel(getnatp(ship.shp_own), aown);
780 if ((ship.shp_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
782 /* Don't shoot yourself */
783 if (ship.shp_own == aown)
785 if (ship.shp_effic < 60)
788 gun = ship.shp_item[I_GUN];
789 shell = ship.shp_item[I_SHELL];
791 if (ship.shp_item[I_MILIT] < 1)
794 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
795 if (shell < SHP_TORP_SHELLS)
796 shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
797 I_SHELL, SHP_TORP_SHELLS - shell);
798 if (shell < SHP_TORP_SHELLS)
803 if (ship.shp_mobil <= 0)
806 erange = ship.shp_effic *
807 techfact(ship.shp_tech, ((double)ship.shp_frnge))
809 erange = (double)roundrange(erange);
810 range = mapdist(ship.shp_x, ship.shp_y, ax, ay);
813 if (!line_of_sight((s_char **)0, ship.shp_x, ship.shp_y, ax, ay))
817 fp = (struct flist *)malloc(sizeof(struct flist));
818 memset(fp, 0, sizeof(struct flist));
819 fp->type = targ_ship;
820 fp->uid = ship.shp_uid;
821 add_to_fired_queue(&fp->queue, list);
823 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
825 hitchance = DTORP_HITCHANCE(range, ship.shp_visib);
826 if (!chance(hitchance))
829 dam += TORP_DAMAGE();
831 range = techfact(ship.shp_tech,
832 ship.shp_frnge * ship.shp_effic / 200.0);
833 range = (double)roundrange(range);
834 if (range < ni.curdist)
836 /* must have gun, shell, and milit to fire */
838 shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
840 /* only need 1 shell, so don't check that */
843 nshot = min(gun, ship.shp_item[I_MILIT]);
844 nshot = min(nshot, ship.shp_glim);
848 fp = (struct flist *)malloc(sizeof(struct flist));
849 memset(fp, 0, sizeof(struct flist));
850 fp->type = targ_ship;
851 fp->uid = ship.shp_uid;
852 add_to_fired_queue(&fp->queue, list);
853 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
854 dam += seagun(ship.shp_effic, nshot);
857 snxtitem_dist(&ni, EF_LAND, ax, ay, 8);
858 while (nxtitem(&ni, &land)) {
859 if (land.lnd_own == 0)
861 if (land.lnd_effic < LAND_MINFIREEFF)
863 /* Can't fire if on a ship */
864 if (land.lnd_ship >= 0)
866 if (land.lnd_land >= 0)
868 /* Gotta have military */
869 if (lnd_getmil(&land) < 1)
871 /* Don't shoot yourself */
872 if (land.lnd_own == aown)
875 rel = getrel(getnatp(land.lnd_own), own);
876 rel2 = getrel(getnatp(land.lnd_own), aown);
878 if ((land.lnd_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
882 range = techfact((int)land.lnd_tech, (double)land.lnd_frg / 2.0);
883 range = (double)roundrange(range);
884 if (range < ni.curdist)
888 if (!has_supply(&land))
891 gun = land.lnd_item[I_GUN];
892 shell = land.lnd_item[I_SHELL];
894 if (land.lnd_item[I_MILIT] == 0 || shell == 0 || gun == 0)
897 dam2 = (int)landunitgun(land.lnd_effic, land.lnd_dam, gun,
898 land.lnd_ammo, shell);
901 fp = (struct flist *)malloc(sizeof(struct flist));
902 memset(fp, 0, sizeof(struct flist));
903 fp->type = targ_unit;
904 fp->uid = land.lnd_uid;
905 add_to_fired_queue(&fp->queue, list);
907 putland(land.lnd_uid, &land);
908 nreport(land.lnd_own, N_FIRE_BACK, player->cnum, 1);
913 * Determine if any nearby gun-equipped sectors are within
914 * range and able to fire at an attacker. Firing sectors
915 * need to have guns, shells, and military. Sector being
916 * attacked is x,y -- attacker is at ax,ay.
919 if (!opt_NO_FORT_FIRE) {
920 snxtsct_dist(&ns, ax, ay, 8);
921 while (nxtsct(&ns, &firing)) {
923 if (firing.sct_type != SCT_FORTR)
925 if (firing.sct_own == 0)
927 rel = getrel(getnatp(firing.sct_own), own);
928 rel2 = getrel(getnatp(firing.sct_own), aown);
930 if ((firing.sct_own != own) &&
931 ((rel != ALLIED) || (rel2 != AT_WAR)))
933 /* Don't shoot yourself */
934 if (firing.sct_own == aown)
936 tech = tfactfire(firing.sct_own, 1.0);
938 if (firing.sct_effic > 59) /* fort bonus */
940 range = (double)roundrange(range);
941 if (range < ns.curdist)
944 gun = firing.sct_item[I_GUN];
945 shell = firing.sct_item[I_SHELL];
948 shell += supply_commod(firing.sct_own,
949 firing.sct_x, firing.sct_y,
951 if (gun == 0 || firing.sct_item[I_MILIT] < 5 || shell == 0)
954 fp = (struct flist *)malloc(sizeof(struct flist));
955 memset(fp, 0, sizeof(struct flist));
956 fp->x = firing.sct_x;
957 fp->y = firing.sct_y;
958 fp->type = targ_land;
959 add_to_fired_queue(&fp->queue, list);
960 nreport(firing.sct_own, N_FIRE_BACK, player->cnum, 1);
963 dam += landgun((int)firing.sct_effic, gun);
967 return ((*nfiring) == 0 ? 0 : (dam / (*nfiring)));
971 use_ammo(struct emp_qelem *list)
973 struct emp_qelem *qp, *next;
983 /* use 1 shell from everyone */
984 for (qp = list->q_forw; qp != list; qp = next) {
986 fp = (struct flist *)qp;
987 if (fp->type == targ_ship) {
988 getship(fp->uid, &ship);
989 item = ship.shp_item;
990 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
991 shell = item[I_SHELL];
992 shell -= SHP_TORP_SHELLS - 1;
995 item[I_SHELL] = shell;
996 putship(ship.shp_uid, &ship);
997 mcp = &mchr[(int)ship.shp_type];
998 mobcost = ship.shp_effic * 0.01 * ship.shp_speed;
999 mobcost = (480.0 / (mobcost +
1000 techfact(ship.shp_tech, mobcost)));
1001 /* mob cost = 1/2 a sect's mob */
1003 ship.shp_mobil -= mobcost;
1005 } else if (fp->type == targ_land) {
1006 getsect(fp->x, fp->y, §);
1007 item = sect.sct_item;
1009 getland(fp->uid, &land);
1010 item = land.lnd_item;
1012 shell = item[I_SHELL];
1016 item[I_SHELL] = shell;
1017 if (fp->type == targ_ship)
1018 putship(ship.shp_uid, &ship);
1019 else if (fp->type == targ_land)
1022 putland(land.lnd_uid, &land);
1024 emp_remque(&fp->queue);
1031 add_to_fired_queue(struct emp_qelem *elem, struct emp_qelem *list)
1033 struct emp_qelem *qp;
1034 struct flist *fp, *ep;
1037 ep = (struct flist *)elem;
1039 /* Don't put them on the list if they're already there */
1040 for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
1041 fp = (struct flist *)qp;
1042 if ((fp->type == targ_ship) && (fp->uid == ep->uid))
1044 if ((fp->type != targ_ship) && (fp->x == ep->x) &&
1050 emp_insque(elem, list);