2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2006, 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 files README, COPYING and CREDITS in the root of the source
23 * tree for related information and legal notices. It is expected
24 * that future projects/authors will amend these files as needed.
28 * multifire.c: Fire at other sectors/ships
30 * Known contributors to this file:
55 targ_land, targ_ship, targ_sub, targ_unit, targ_bogus
59 struct emp_qelem queue; /* list of fired things */
60 int type; /* ship? otherwise sector */
61 int uid; /* ship uid */
62 coord x, y; /* sector coords */
63 int defdam; /* damage defenders did */
64 int victim; /* who I was shooting at */
73 static void add_to_fired_queue(struct emp_qelem *, struct emp_qelem *);
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);
82 static void do_defdam(struct emp_qelem *, double);
83 static int quiet_bigdef(int, struct emp_qelem *, natid, natid, coord,
85 static void use_ammo(struct emp_qelem *);
90 static int ef_with_guns[] = { EF_SECTOR, EF_SHIP, EF_LAND, EF_BAD };
115 enum targ_type target, attacker, orig_attacker;
118 struct nstr_item nbst;
124 struct emp_qelem fired, defended;
129 emp_initque(&defended);
130 if (!(p = getstarg(player->argp[1],
131 "Firing from ship(s), sect(s), or land unit(s)? ",
134 type = ef_byname_from(p, ef_with_guns);
135 if (type == EF_SECTOR) {
136 if (opt_NO_FORT_FIRE) {
137 pr("Fort firing is disabled.\n");
140 orig_attacker = attacker = targ_land;
142 } else if (type == EF_SHIP) {
143 orig_attacker = attacker = targ_ship;
144 } else if (type == EF_LAND) {
145 orig_attacker = attacker = targ_unit;
147 pr("Ships, land units or sectors only!\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, &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);
557 pr("Wind deflects shell%s.\n", splur(shots));
558 /* dam = (int)((double)dam / 2.0);*/
561 (double)((double)(90 - (random() % 11)) /
571 nreport(player->cnum, N_SCT_SHELL, vict, 1);
572 if (vict && vict != player->cnum)
574 "Country #%d shelled sector %s for %d damage.\n",
575 player->cnum, xyas(x, y, vict), dam);
576 pr("Shell%s hit sector %s for %d damage.\n",
577 splur(shots), xyas(x, y, player->cnum), dam);
578 /* Ok, it wasn't a bogus target, so do damage. */
579 if (target != targ_bogus)
580 sectdamage(&vsect, dam, 0);
583 nreport(player->cnum, N_SHP_SHELL, vict, 1);
586 if ((target != targ_sub) ||
587 ((vship.shp_rflags & RET_DCHRGED) == 0))
588 check_retreat_and_do_shipdamage(&vship, dam);
590 shipdamage(&vship, dam);
593 "Country #%d shelled %s in %s for %d damage.\n",
594 player->cnum, prship(&vship),
595 xyas(vship.shp_x, vship.shp_y, vict), dam);
597 pr("Shell%s hit %s in %s for %d damage.\n",
598 splur(shots), prsub(&vship),
599 xyas(vship.shp_x, vship.shp_y, player->cnum), dam);
601 if (vship.shp_effic < SHIP_MINEFF)
602 pr("%s sunk!\n", prsub(&vship));
606 /* Ok, now, check if we had a bogus target. If so,
607 just continue on, since there is no defender. */
608 if (target == targ_bogus)
610 if (attacker == targ_unit) {
611 attacker = targ_land;
612 getsect(fland.lnd_x, fland.lnd_y, &fsect);
615 defend(&fired, &defended, target, attacker, &vsect, &fsect,
616 &vship, &fship, fx, fy, &ndefending);
622 putship(vship.shp_uid, &vship);
625 if ((totaldefdam == 0) && (target == targ_ship))
626 if (vship.shp_rflags & RET_INJURED)
627 retreat_ship(&vship, 'h');
633 if ((target == targ_ship) || (target == targ_sub)) {
634 if (fship.shp_effic > SHIP_MINEFF) {
635 shp_missdef(&fship, vict);
638 putship(fship.shp_uid, &fship);
645 odds = ((double)ndefending) / ((double)nfiring);
648 do_defdam(&fired, odds);
653 defend(struct emp_qelem *al, struct emp_qelem *dl, enum targ_type target,
654 enum targ_type attacker, struct sctstr *vsect, struct sctstr *fsect,
655 struct shpstr *vship, struct shpstr *fship, int fx, int fy, int *nd)
659 int vict, nfiring = 0;
663 if (attacker == targ_land)
664 aown = fsect->sct_own;
666 aown = fship->shp_own;
668 if (target == targ_land)
669 vict = vsect->sct_own;
671 vict = vship->shp_own;
674 (dam = quiet_bigdef(attacker, dl, vict, aown, fx, fy, &nfiring))) {
677 fp = malloc(sizeof(struct flist));
678 memset(fp, 0, sizeof(struct flist));
683 fp->x = fsect->sct_x;
684 fp->y = fsect->sct_y;
685 fp->type = targ_land;
688 fp->type = targ_ship;
689 fp->uid = fship->shp_uid;
692 emp_insque(&fp->queue, al);
699 do_defdam(struct emp_qelem *list, double odds)
702 int dam, vict, first = 1;
706 struct emp_qelem *qp, *next;
708 for (qp = list->q_forw; qp != list; qp = next) {
710 fp = (struct flist *)qp;
711 if (fp->type == targ_ship) {
712 if (!getship(fp->uid, &ship) || !ship.shp_own)
717 pr("\nDefenders fire back!\n");
720 dam = (odds * (double)fp->defdam);
722 if (fp->type == targ_ship) {
724 pr("Return fire hit %s in %s for %d damage.\n",
726 xyas(ship.shp_x, ship.shp_y, player->cnum), dam);
729 "Return fire hit %s in %s for %d damage.\n",
730 prsub(&ship), xyas(ship.shp_x, ship.shp_y, vict), dam);
731 shipdamage(&ship, dam);
732 putship(ship.shp_uid, &ship);
734 getsect(fp->x, fp->y, §);
736 pr("Return fire hit sector %s for %d damage.\n",
737 xyas(fp->x, fp->y, player->cnum), dam);
738 sectdamage(§, dam, 0);
741 wu(0, vict, "Return fire hit sector %s for %d damage.\n",
742 xyas(fp->x, fp->y, vict), dam);
744 emp_remque(&fp->queue);
750 quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown,
751 coord ax, coord ay, int *nfiring)
754 double range, erange, hitchance;
758 int dam, dam2, rel, rel2;
760 struct sctstr firing;
768 snxtitem_dist(&ni, EF_SHIP, ax, ay, 8);
769 while (nxtitem(&ni, &ship)) {
770 if (ship.shp_own == 0)
773 if ((mchr[(int)ship.shp_type].m_flags & M_SUB) &&
774 (attacker == targ_land))
777 rel = getrel(getnatp(ship.shp_own), own);
778 rel2 = getrel(getnatp(ship.shp_own), aown);
779 if ((ship.shp_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
781 /* Don't shoot yourself */
782 if (ship.shp_own == aown)
784 if (ship.shp_effic < 60)
787 gun = ship.shp_item[I_GUN];
788 shell = ship.shp_item[I_SHELL];
790 if (ship.shp_item[I_MILIT] < 1)
793 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
794 if (shell < SHP_TORP_SHELLS)
795 shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
796 I_SHELL, SHP_TORP_SHELLS - shell);
797 if (shell < SHP_TORP_SHELLS)
802 if (ship.shp_mobil <= 0)
805 erange = ship.shp_effic *
806 techfact(ship.shp_tech, ((double)ship.shp_frnge))
808 erange = (double)roundrange(erange);
809 range = mapdist(ship.shp_x, ship.shp_y, ax, ay);
812 if (!line_of_sight(NULL, ship.shp_x, ship.shp_y, ax, ay))
816 fp = malloc(sizeof(struct flist));
817 memset(fp, 0, sizeof(struct flist));
818 fp->type = targ_ship;
819 fp->uid = ship.shp_uid;
820 add_to_fired_queue(&fp->queue, list);
822 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
824 hitchance = DTORP_HITCHANCE(range, ship.shp_visib);
825 if (!chance(hitchance))
828 dam += TORP_DAMAGE();
830 range = techfact(ship.shp_tech,
831 ship.shp_frnge * ship.shp_effic / 200.0);
832 range = (double)roundrange(range);
833 if (range < ni.curdist)
835 /* must have gun, shell, and milit to fire */
837 shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
839 /* only need 1 shell, so don't check that */
842 nshot = MIN(gun, ship.shp_item[I_MILIT]);
843 nshot = MIN(nshot, ship.shp_glim);
847 fp = malloc(sizeof(struct flist));
848 memset(fp, 0, sizeof(struct flist));
849 fp->type = targ_ship;
850 fp->uid = ship.shp_uid;
851 add_to_fired_queue(&fp->queue, list);
852 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
853 dam += seagun(ship.shp_effic, nshot);
856 snxtitem_dist(&ni, EF_LAND, ax, ay, 8);
857 while (nxtitem(&ni, &land)) {
858 if (land.lnd_own == 0)
860 if (land.lnd_effic < LAND_MINFIREEFF)
862 /* Can't fire if on a ship */
863 if (land.lnd_ship >= 0)
865 if (land.lnd_land >= 0)
867 /* Gotta have military */
868 if (lnd_getmil(&land) < 1)
870 /* Don't shoot yourself */
871 if (land.lnd_own == aown)
874 rel = getrel(getnatp(land.lnd_own), own);
875 rel2 = getrel(getnatp(land.lnd_own), aown);
877 if ((land.lnd_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
881 range = techfact((int)land.lnd_tech, (double)land.lnd_frg / 2.0);
882 range = (double)roundrange(range);
883 if (range < ni.curdist)
887 if (!has_supply(&land))
890 gun = land.lnd_item[I_GUN];
891 shell = land.lnd_item[I_SHELL];
893 if (land.lnd_item[I_MILIT] == 0 || shell == 0 || gun == 0)
896 dam2 = (int)landunitgun(land.lnd_effic, land.lnd_dam, gun,
897 land.lnd_ammo, shell);
900 fp = malloc(sizeof(struct flist));
901 memset(fp, 0, sizeof(struct flist));
902 fp->type = targ_unit;
903 fp->uid = land.lnd_uid;
904 add_to_fired_queue(&fp->queue, list);
906 putland(land.lnd_uid, &land);
907 nreport(land.lnd_own, N_FIRE_BACK, player->cnum, 1);
912 * Determine if any nearby gun-equipped sectors are within
913 * range and able to fire at an attacker. Firing sectors
914 * need to have guns, shells, and military. Sector being
915 * attacked is x,y -- attacker is at ax,ay.
918 if (!opt_NO_FORT_FIRE) {
919 snxtsct_dist(&ns, ax, ay, 8);
920 while (nxtsct(&ns, &firing)) {
922 if (firing.sct_type != SCT_FORTR)
924 if (firing.sct_own == 0)
926 rel = getrel(getnatp(firing.sct_own), own);
927 rel2 = getrel(getnatp(firing.sct_own), aown);
929 if ((firing.sct_own != own) &&
930 ((rel != ALLIED) || (rel2 != AT_WAR)))
932 /* Don't shoot yourself */
933 if (firing.sct_own == aown)
935 tech = tfactfire(firing.sct_own, 1.0);
937 if (firing.sct_effic > 59) /* fort bonus */
939 range = (double)roundrange(range);
940 if (range < ns.curdist)
943 gun = firing.sct_item[I_GUN];
944 shell = firing.sct_item[I_SHELL];
947 shell += supply_commod(firing.sct_own,
948 firing.sct_x, firing.sct_y,
950 if (gun == 0 || firing.sct_item[I_MILIT] < 5 || shell == 0)
953 fp = malloc(sizeof(struct flist));
954 memset(fp, 0, sizeof(struct flist));
955 fp->x = firing.sct_x;
956 fp->y = firing.sct_y;
957 fp->type = targ_land;
958 add_to_fired_queue(&fp->queue, list);
959 nreport(firing.sct_own, N_FIRE_BACK, player->cnum, 1);
962 dam += landgun((int)firing.sct_effic, gun);
966 return *nfiring == 0 ? 0 : dam / *nfiring;
970 use_ammo(struct emp_qelem *list)
972 struct emp_qelem *qp, *next;
982 /* use 1 shell from everyone */
983 for (qp = list->q_forw; qp != list; qp = next) {
985 fp = (struct flist *)qp;
986 if (fp->type == targ_ship) {
987 getship(fp->uid, &ship);
988 item = ship.shp_item;
989 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
990 shell = item[I_SHELL];
991 shell -= SHP_TORP_SHELLS - 1;
994 item[I_SHELL] = shell;
995 putship(ship.shp_uid, &ship);
996 mcp = &mchr[(int)ship.shp_type];
997 mobcost = ship.shp_effic * 0.01 * ship.shp_speed;
998 mobcost = (480.0 / (mobcost +
999 techfact(ship.shp_tech, mobcost)));
1000 /* mob cost = 1/2 a sect's mob */
1002 ship.shp_mobil -= mobcost;
1004 } else if (fp->type == targ_land) {
1005 getsect(fp->x, fp->y, §);
1006 item = sect.sct_item;
1008 getland(fp->uid, &land);
1009 item = land.lnd_item;
1011 shell = item[I_SHELL];
1015 item[I_SHELL] = shell;
1016 if (fp->type == targ_ship)
1017 putship(ship.shp_uid, &ship);
1018 else if (fp->type == targ_land)
1021 putland(land.lnd_uid, &land);
1023 emp_remque(&fp->queue);
1030 add_to_fired_queue(struct emp_qelem *elem, struct emp_qelem *list)
1032 struct emp_qelem *qp;
1033 struct flist *fp, *ep;
1036 ep = (struct flist *)elem;
1038 /* Don't put them on the list if they're already there */
1039 for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
1040 fp = (struct flist *)qp;
1041 if ((fp->type == targ_ship) && (fp->uid == ep->uid))
1043 if ((fp->type != targ_ship) && (fp->x == ep->x) &&
1049 emp_insque(elem, list);