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",
192 fland.lnd_uid, LAND_MINFIREEFF);
195 resupply_commod(&fland, I_SHELL); /* Get more shells */
196 putland(fland.lnd_uid, &fland);
197 if (fland.lnd_item[I_SHELL] == 0) {
198 pr("%s -- not enough shells\n", prland(&fland));
201 } else if (attacker == targ_ship) {
202 if (!getship(item.ship.shp_uid, &fship))
204 if (item.ship.shp_own != player->cnum)
206 if (item.ship.shp_item[I_MILIT] < 1) {
207 pr("Not enough mil on ship #%d\n", item.ship.shp_uid);
210 gun = item.ship.shp_item[I_GUN];
211 gun = MIN(gun, item.ship.shp_glim);
212 if (item.ship.shp_frnge == 0) {
213 pr("Ships %d cannot fire guns!\n", item.ship.shp_uid);
217 pr("Not enough guns on ship #%d\n", item.ship.shp_uid);
220 if (item.ship.shp_item[I_SHELL] == 0) {
221 pr("Not enough shells on ship #%d\n", item.ship.shp_uid);
224 if (item.ship.shp_effic < 60) {
225 pr("Ship #%d is crippled!\n", item.ship.shp_uid);
228 fshipno = fship.shp_uid;
229 } else if (attacker == targ_land) {
230 if (!getsect(item.sect.sct_x, item.sect.sct_y, &fsect))
232 if (item.sect.sct_own != player->cnum)
234 if (item.sect.sct_type != SCT_FORTR)
236 if (item.sect.sct_effic < FORTEFF) {
237 pr("Fort not efficient enough to fire!\n");
240 if (item.sect.sct_item[I_GUN] == 0) {
241 pr("Not enough guns in sector %s!\n",
242 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
245 if (item.sect.sct_item[I_SHELL] == 0) {
246 pr("Not enough shells in sector %s!\n",
247 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
250 if (item.sect.sct_item[I_MILIT] < 5) {
251 pr("Not enough military in sector %s!\n",
252 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
255 pr("\nSector %s firing\n",
256 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
258 if ((ptr = getstarg(player->argp[3], "Firing at? ", buf)) == 0
261 if (player->aborted) {
262 pr("Fire aborted.\n");
266 (void)strcpy(vbuf, ptr);
271 if (target == targ_ship) {
272 vshipno = atoi(vbuf);
273 if (vshipno < 0 || !getship(vshipno, &vship) ||
275 pr("No such ship exists!\n");
278 target = (mchr[(int)vship.shp_type].m_flags & M_SUB) ?
279 targ_sub : targ_ship;
280 vict = vship.shp_own;
283 if (!getsect(x, y, &vsect)) {
284 pr("No such sector exists!\n");
288 if (!sarg_xy(vbuf, &x, &y) || !getsect(x, y, &vsect)) {
289 pr("No such sector exists!\n");
292 /* We check the sector type, but we only use it for damage, not
293 reporting. That way, you don't get extra information you wouldn't
294 normally get. Besides, what if they want to slam water? :) */
295 if (vsect.sct_type == SCT_SANCT || vsect.sct_type == SCT_WATER)
299 vict = vsect.sct_own;
303 if (attacker == targ_ship) {
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 = fship.shp_item[I_MILIT]) < 1) {
326 pr("Not enough military for firing crew.\n");
329 gun = fship.shp_item[I_GUN];
330 gun = MIN(gun, fship.shp_glim);
331 if (fship.shp_frnge == 0 || gun == 0) {
332 pr("Insufficient arms.\n");
335 shell = fship.shp_item[I_SHELL];
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 /* Don't tell it's a sub */
356 } else if (shell < 2) {
357 pr("Not enough shells for depth charge!\n");
361 gun = MIN(gun, shell * 2);
362 gun = MIN(gun, mil / 2);
365 guneff = seagun(fship.shp_effic, shots);
367 shell -= ldround(((double)shots) / 2.0, 1);
368 fship.shp_item[I_SHELL] = shell;
369 if (opt_NOMOBCOST == 0)
370 fship.shp_mobil = MAX(fship.shp_mobil - 15, -100);
371 putship(fship.shp_uid, &fship);
372 } else if (attacker == targ_unit) {
373 if (fland.lnd_own != player->cnum) {
374 pr("Not your unit!\n");
378 if (target == targ_land) {
379 if (fland.lnd_x == vsect.sct_x
380 && fland.lnd_y == vsect.sct_y) {
381 pr("You can't fire upon yourself!\n");
389 if (fland.lnd_frg == 0) {
390 pr("Unit %d cannot fire!\n", fland.lnd_uid);
393 if (fland.lnd_item[I_SHELL] == 0) {
394 pr("%s -- not enough shells\n", prland(&fland));
398 shell = fland.lnd_item[I_SHELL];
400 range = techfact((int)fland.lnd_tech,
401 (double)fland.lnd_frg / 2.0);
402 range2 = (double)roundrange(range);
403 pr("range is %.2f (%.2f)\n", range2, range);
404 if (target == targ_sub) {
405 /* Don't tell it's a sub */
409 gun = fland.lnd_item[I_GUN];
411 pr("%s -- not enough guns\n", prland(&fland));
415 dam = (int)landunitgun(fland.lnd_effic, fland.lnd_dam, gun,
416 fland.lnd_ammo, shell);
417 if (target == targ_ship) {
418 if (chance(((double)fland.lnd_acc) / 100.0))
419 dam = ldround(((double)dam / 2.0), 1);
422 resupply_commod(&fland, I_SHELL); /* Get more shells */
423 putland(fland.lnd_uid, &fland);
427 if (fsect.sct_own != player->cnum ||
428 fsect.sct_type != SCT_FORTR) {
429 pr("No fortress at %s\n", xyas(fsect.sct_x,
430 fsect.sct_y, player->cnum));
433 if (target == targ_land) {
434 if (fsect.sct_x == vsect.sct_x
435 && fsect.sct_y == vsect.sct_y) {
436 pr("You can't fire upon yourself!\n");
440 attacker = targ_land;
441 if ((gun = fsect.sct_item[I_GUN]) == 0) {
442 pr("Insufficient arms.\n");
445 shell = fsect.sct_item[I_SHELL];
447 shell += supply_commod(fsect.sct_own, fsect.sct_x,
448 fsect.sct_y, I_SHELL, 1);
453 if (fsect.sct_item[I_MILIT] < 5) {
454 pr("Not enough military for firing crew.\n");
459 range = tfactfire(player->cnum, 7.0);
460 if (fsect.sct_effic > 59)
462 range2 = (double)roundrange(range);
463 pr("range is %.2f (%.2f)\n", range2, range);
464 if (target == targ_sub) {
465 /* Don't tell it's a sub */
468 guneff = landgun((int)fsect.sct_effic, gun);
471 fsect.sct_item[I_SHELL] = shell;
474 trange = mapdist(x, y, fx, fy);
475 if (trange > range2) {
476 pr("Target out of range.\n");
481 pr("Target out of range. Thud.\n");
484 pr("Target ship out of range. Splash.\n");
493 fland.lnd_mission = 0;
494 putland(fland.lnd_uid, &fland);
497 fship.shp_mission = 0;
498 putship(fship.shp_uid, &fship);
503 if (target == targ_bogus) {
504 if (vsect.sct_type == SCT_SANCT) {
505 pr("%s is a %s!!\n", vbuf,
506 dchr[SCT_SANCT].d_name);
508 } else if (vsect.sct_type == SCT_WATER) {
509 pr("You must specify a ship in sector %s!\n",
517 if (!trechk(player->cnum, vict, SEAFIR))
521 if (!trechk(player->cnum, vict, SUBFIR))
526 if (!trechk(player->cnum, vict, LANFIR))
534 if (target == targ_land) {
535 natp = getnatp(player->cnum);
536 rel = getrel(natp, vict);
537 if ((rel != AT_WAR) && (player->cnum != vict) &&
538 (vict) && (vsect.sct_oldown != player->cnum)) {
539 pr("You're not at war with them!\n");
549 if (vship.shp_rflags & RET_DCHRGED)
550 retreat_ship(&vship, 'd');
555 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_HELPLESS)
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 = 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, ship.shp_frnge) / 100.0;
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);