home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume17 / gbp / part08 < prev    next >
Encoding:
Internet Message Format  |  1993-03-20  |  54.3 KB

  1. Path: uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v17i020:  gbp - Galactic Bloodshed+, an empire-like war game, Part08/21
  5. Message-ID: <4548@master.CNA.TEK.COM>
  6. Date: 12 Feb 93 17:30:56 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 1913
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1699
  11.  
  12. Submitted-by: deragon@harpo.cs.nyu.edu (Seeker)
  13. Posting-number: Volume 17, Issue 20
  14. Archive-name: gbp/Part08
  15. Supersedes: gb3: Volume 10, Issue 1-14
  16. Environment: sockets, curses
  17.  
  18.  
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 8 (of 21)."
  27. # Contents:  buildfiles.sh user/order.c user/shootblast.c
  28. # Wrapped by billr@saab on Fri Feb 12 09:14:25 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'buildfiles.sh' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'buildfiles.sh'\"
  32. else
  33. echo shar: Extracting \"'buildfiles.sh'\" \(96 characters\)
  34. sed "s/^X//" >'buildfiles.sh' <<'END_OF_FILE'
  35. X#!/bin/sh
  36. X
  37. Xcat user/build.c1 user/build.c2 > user/build.c
  38. Xrm user/build.c1 user/build.c2
  39. Xexit 0
  40. END_OF_FILE
  41. if test 96 -ne `wc -c <'buildfiles.sh'`; then
  42.     echo shar: \"'buildfiles.sh'\" unpacked with wrong size!
  43. fi
  44. chmod +x 'buildfiles.sh'
  45. # end of 'buildfiles.sh'
  46. fi
  47. if test -f 'user/order.c' -a "${1}" != "-c" ; then 
  48.   echo shar: Will not clobber existing file \"'user/order.c'\"
  49. else
  50. echo shar: Extracting \"'user/order.c'\" \(32144 characters\)
  51. sed "s/^X//" >'user/order.c' <<'END_OF_FILE'
  52. X/*
  53. X * Galactic Bloodshed, copyright (c) 1989 by Robert P. Chansky,
  54. X * smq@ucscb.ucsc.edu, mods by people in GB_copyright.h. Restrictions in
  55. X * GB_copyright.h.
  56. X * 
  57. X * order.c -- give orders to ship
  58. X */
  59. X
  60. X#include <curses.h>
  61. X#include <ctype.h>
  62. X#include <signal.h>
  63. X#include <math.h>
  64. X#include <strings.h>
  65. X
  66. X#include "GB_copyright.h"
  67. X#define EXTERN extern
  68. X#include "vars.h"
  69. X#include "ships.h"
  70. X#include "races.h"
  71. X#include "power.h"
  72. X#include "buffers.h"
  73. X
  74. Xvoid            order(int, int, int);
  75. Xvoid            give_orders(int, int, int, shiptype *);
  76. Xchar           *prin_aimed_at(int, int, shiptype *);
  77. Xchar           *prin_ship_dest(int, int, shiptype *);
  78. Xvoid            mk_expl_aimed_at(int, int, shiptype *);
  79. Xvoid            DispOrdersHeader(int, int);
  80. Xvoid            DispOrders(int, int, shiptype *);
  81. Xvoid            route(int, int, int);
  82. X#include "proto.h"
  83. X
  84. Xvoid 
  85. Xorder(int Playernum, int Governor, int APcount)
  86. X{
  87. X    int             shipno, nextshipno;
  88. X    shiptype       *ship;
  89. X
  90. X    if (argn == 1) {    /* display all ship orders */
  91. X        DispOrdersHeader(Playernum, Governor);
  92. X        nextshipno = start_shiplist(Playernum, Governor, "test");
  93. X        while (shipno = do_shiplist(&ship, &nextshipno))
  94. X            if (ship->owner == Playernum && authorized(Governor, ship)) {
  95. X                DispOrders(Playernum, Governor, ship);
  96. X                free(ship);
  97. X            } else
  98. X                free(ship);
  99. X    } else if (argn >= 2) {
  100. X        DispOrdersHeader(Playernum, Governor);
  101. X        nextshipno = start_shiplist(Playernum, Governor, args[1]);
  102. X        while (shipno = do_shiplist(&ship, &nextshipno))
  103. X            if (in_list(Playernum, args[1], ship, &nextshipno) &&
  104. X                authorized(Governor, ship)) {
  105. X                if (argn > 2)
  106. X                    give_orders(Playernum, Governor, APcount, ship);
  107. X                DispOrders(Playernum, Governor, ship);
  108. X                free(ship);
  109. X            } else
  110. X                free(ship);
  111. X    } else
  112. X        notify(Playernum, Governor, "I don't understand what you mean.\n");
  113. X}
  114. X
  115. Xvoid 
  116. Xgive_orders(int Playernum, int Governor, int APcount, shiptype * ship)
  117. X{
  118. X    int             i = 0, j = 0;
  119. X    placetype       where, pl;
  120. X    planettype     *planet;
  121. X    shiptype       *tmpship;
  122. X
  123. X    if (!ship->active) {
  124. X        sprintf(buf, "%s is irradiated (%d); it cannot be give orders.\n",
  125. X            Ship(ship), ship->rad);
  126. X        notify(Playernum, Governor, buf);
  127. X        return;
  128. X    }
  129. X    if (ship->type != OTYPE_TRANSDEV && !ship->popn && Max_crew(ship)) {
  130. X        sprintf(buf, "%s has no crew and is not a robotic ship.\n", Ship(ship));
  131. X        notify(Playernum, Governor, buf);
  132. X        return;
  133. X    }
  134. X    if (match(args[2], "defense")) {
  135. X        if (can_bombard(ship)) {
  136. X            if (match(args[3], "off"))
  137. X                ship->protect.planet = 0;
  138. X            else
  139. X                ship->protect.planet = 1;
  140. X        } else {
  141. X            notify(Playernum, Governor, "That ship cannot be assigned those orders.\n");
  142. X            return;
  143. X        }
  144. X    } else if (match(args[2], "scatter")) {
  145. X        if (ship->type != STYPE_MISSILE) {
  146. X            notify(Playernum, Governor, "Only missiles can be given this order.\n");
  147. X            return;
  148. X        }
  149. X        ship->special.impact.scatter = 1;
  150. X    } else if (match(args[2], "impact")) {
  151. X        int             x, y;
  152. X        if (ship->type != STYPE_MISSILE) {
  153. X            notify(Playernum, Governor, "Only missiles can be designated for this.\n");
  154. X            return;
  155. X        }
  156. X        sscanf(args[3], "%d,%d", &x, &y);
  157. X        ship->special.impact.x = x;
  158. X        ship->special.impact.y = y;
  159. X        ship->special.impact.scatter = 0;
  160. X    } else if (match(args[2], "jump")) {
  161. X        if (ship->docked) {
  162. X            notify(Playernum, Governor, "That ship is docked. Use 'launch' or 'undock' first.\n");
  163. X            return;
  164. X        }
  165. X        if (ship->hyper_drive.has) {
  166. X            if (match(args[3], "off"))
  167. X                ship->hyper_drive.on = 0;
  168. X            else {
  169. X                if (ship->whatdest != LEVEL_STAR && ship->whatdest != LEVEL_PLAN) {
  170. X                    notify(Playernum, Governor, "Destination must be star or planet.\n");
  171. X                    return;
  172. X                }
  173. X                ship->hyper_drive.on = 1;
  174. X                ship->navigate.on = 0;
  175. X                if (ship->mounted) {
  176. X                    ship->hyper_drive.charge = 1;
  177. X                    ship->hyper_drive.ready = 1;
  178. X                }
  179. X            }
  180. X        } else {
  181. X            notify(Playernum, Governor, "This ship does not have hyper drive capability.\n");
  182. X            return;
  183. X        }
  184. X#ifdef THRESHLOADING
  185. X    } else if (match(args[2], "threshload")) {
  186. X    /* CWL threshold loading */
  187. X      if (argn == 3) { /* Clear all thresholds */
  188. X    int i;
  189. X    for (i=0;i<=TH_CRYSTALS;i++) 
  190. X      ship->threshload[i] = 0;
  191. X    notify(Playernum, Governor, "All threshloads cleared.\n");
  192. X      } else if (argn == 4 || argn == 5) { /* Clear one threshold */
  193. X    unsigned amount;
  194. X    char *c;
  195. X    amount = (argn == 5) ? (unsigned)atoi(args[4]) : 1000; 
  196. X    c = args[3];
  197. X    while (*c) {
  198. X      if (*c == 'r') {
  199. X        if (amount > ship->max_resource)
  200. X          ship->threshload[TH_RESOURCE] = ship->max_resource;
  201. X        else
  202. X          ship->threshload[TH_RESOURCE] = amount;
  203. X      } else if (*c == 'd') {
  204. X        if (amount > ship->max_destruct)
  205. X          ship->threshload[TH_DESTRUCT] = ship->max_destruct;
  206. X        else
  207. X          ship->threshload[TH_DESTRUCT] = amount;
  208. X      } else if (*c == 'f') {
  209. X        if (amount > (int)ship->max_fuel)
  210. X          ship->threshload[TH_FUEL] = ship->max_fuel;
  211. X        else
  212. X          ship->threshload[TH_FUEL] = amount;
  213. X      } else if (*c == 'x') {
  214. X        if (amount > Max_crystals(s))
  215. X          ship->threshload[TH_CRYSTALS] = Max_crystals(s);
  216. X        else
  217. X          ship->threshload[TH_CRYSTALS] = amount;
  218. X      } else 
  219. X         notify(Playernum, Governor, "Unknown commodity; use rdfx.\n");
  220. X      c++;
  221. X    } /* end while */
  222. X      }
  223. X      else
  224. X    notify(Playernum, Governor, "threshold <rdfx> [amount]\n");
  225. X#endif 
  226. X#ifdef AUTOSCRAP
  227. X    } else if (match(args[2], "autoscrap")) { /* AUTOSCRAP */
  228. X      ship->autoscrap = !ship->autoscrap;
  229. X#endif 
  230. X    } else if (match(args[2], "protect")) {
  231. X        if (argn > 3)
  232. X            sscanf(args[3] + (args[3][0] == '#'), "%d", &j);
  233. X        else
  234. X            j = 0;
  235. X        if (j == ship->number) {
  236. X            notify(Playernum, Governor, "You can't do that.\n");
  237. X            return;
  238. X        }
  239. X        if (can_bombard(ship)) {
  240. X            if (!j) {
  241. X                ship->protect.on = 0;
  242. X            } else {
  243. X                ship->protect.on = 1;
  244. X                ship->protect.ship = j;
  245. X            }
  246. X        } else {
  247. X            notify(Playernum, Governor, "That ship cannot protect.\n");
  248. X            return;
  249. X        }
  250. X    } else if (match(args[2], "navigate")) {
  251. X        if (argn >= 5) {
  252. X            ship->navigate.on = 1;
  253. X            ship->navigate.bearing = atoi(args[3]);
  254. X            ship->navigate.turns = atoi(args[4]);
  255. X        } else
  256. X            ship->navigate.on = 0;
  257. X        if (ship->hyper_drive.on)
  258. X            ship->hyper_drive.on = 0;
  259. X    } else if (match(args[2], "switch")) {
  260. X        if (ship->type == OTYPE_FACTORY) {
  261. X            notify(Playernum, Governor, "Use \"on\" to bring factory online.\n");
  262. X            return;
  263. X        }
  264. X        if (has_switch(ship)) {
  265. X            if (ship->whatorbits == LEVEL_SHIP) {
  266. X                notify(Playernum, Governor, "That ship is being transported.\n");
  267. X                return;
  268. X            }
  269. X            ship->on = !ship->on;
  270. X        } else {
  271. X            sprintf(buf, "That ship does not have an on/off setting.\n");
  272. X            notify(Playernum, Governor, buf);
  273. X            return;
  274. X        }
  275. X        if (ship->on) {
  276. X            switch (ship->type) {
  277. X            case STYPE_MINE:
  278. X                notify(Playernum, Governor, "Mine armed and ready.\n");
  279. X                break;
  280. X            case OTYPE_TRANSDEV:
  281. X                notify(Playernum, Governor, "Transporter ready to receive.\n");
  282. X                break;
  283. X            default:
  284. X                break;
  285. X            }
  286. X        } else {
  287. X            switch (ship->type) {
  288. X            case STYPE_MINE:
  289. X                notify(Playernum, Governor, "Mine disarmed.\n");
  290. X                break;
  291. X            case OTYPE_TRANSDEV:
  292. X                notify(Playernum, Governor, "No longer receiving.\n");
  293. X                break;
  294. X            default:
  295. X                break;
  296. X            }
  297. X        }
  298. X    } else if (match(args[2], "destination")) {
  299. X        if (speed_rating(ship)) {
  300. X            if (ship->docked) {
  301. X                notify(Playernum, Governor, "That ship is docked; use undock or launch first.\n");
  302. X                return;
  303. X            }
  304. X            where = Getplace(Playernum, Governor, args[3], 1);
  305. X            if (!where.err) {
  306. X                if (where.level == LEVEL_SHIP) {
  307. X                    (void) getship(&tmpship, where.shipno);
  308. X                    if (!followable(ship, tmpship)) {
  309. X                        notify(Playernum, Governor, "Warning: that ship is out of range.\n");
  310. X                        free(tmpship);
  311. X                        return;
  312. X                    }
  313. X                    free(tmpship);
  314. X                    ship->destshipno = where.shipno;
  315. X                    ship->whatdest = LEVEL_SHIP;
  316. X                } else {
  317. X                    /* to foil cheaters */
  318. X                    if (where.level != LEVEL_UNIV &&
  319. X                        ((ship->storbits != where.snum) && where.level != LEVEL_STAR) &&
  320. X                        isclr(Stars[where.snum]->explored, ship->owner)) {
  321. X                        notify(Playernum, Governor, "You haven't explored this system.\n");
  322. X                        return;
  323. X                    }
  324. X                    ship->whatdest = where.level;
  325. X                    ship->deststar = where.snum;
  326. X                    ship->destpnum = where.pnum;
  327. X                }
  328. X            } else
  329. X                return;
  330. X        } else {
  331. X            notify(Playernum, Governor, "That ship cannot be launched.\n");
  332. X            return;
  333. X        }
  334. X    } else if (match(args[2], "evade")) {
  335. X        if (Max_crew(ship) && Max_speed(ship)) {
  336. X            if (match(args[3], "on"))
  337. X                ship->protect.evade = 1;
  338. X            else if (match(args[3], "off"))
  339. X                ship->protect.evade = 0;
  340. X        } else
  341. X            return;
  342. X    } else if (match(args[2], "bombard")) {
  343. X        if (ship->type != OTYPE_OMCL) {
  344. X            if (can_bombard(ship)) {
  345. X                if (match(args[3], "off"))
  346. X                    ship->bombard = 0;
  347. X                else if (match(args[3], "on"))
  348. X                    ship->bombard = 1;
  349. X            } else
  350. X                notify(Playernum, Governor, "This type of ship cannot be set to retaliate.\n");
  351. X        }
  352. X    } else if (match(args[2], "retaliate")) {
  353. X        if (ship->type != OTYPE_OMCL) {
  354. X            if (can_bombard(ship)) {
  355. X                if (match(args[3], "off"))
  356. X                    ship->protect.self = 0;
  357. X                else if (match(args[3], "on"))
  358. X                    ship->protect.self = 1;
  359. X            } else
  360. X                notify(Playernum, Governor, "This type of ship cannot be set to retaliate.\n");
  361. X        }
  362. X    } else if (match(args[2], "focus")) {
  363. X        if (ship->laser) {
  364. X            if (match(args[3], "on"))
  365. X                ship->focus = 1;
  366. X            else
  367. X                ship->focus = 0;
  368. X        } else
  369. X            notify(Playernum, Governor, "No laser.\n");
  370. X    } else if (match(args[2], "laser")) {
  371. X        if (ship->laser) {
  372. X            if (can_bombard(ship)) {
  373. X                if (ship->mounted) {
  374. X                    if (match(args[3], "on"))
  375. X                        ship->fire_laser = atoi(args[4]);
  376. X                    else
  377. X                        ship->fire_laser = 0;
  378. X                } else
  379. X                    notify(Playernum, Governor, "You do not have a crystal mounted.\n");
  380. X            } else
  381. X                notify(Playernum, Governor, "This type of ship cannot be set to retaliate.\n");
  382. X        } else
  383. X            notify(Playernum, Governor, "This ship is not equipped with combat lasers.\n");
  384. X    } else if (match(args[2], "merchant")) {
  385. X        if (match(args[3], "off"))
  386. X            ship->merchant = 0;
  387. X        else {
  388. X            j = atoi(args[3]);
  389. X            if (j < 0 || j > MAX_ROUTES) {
  390. X                notify(Playernum, Governor, "Bad route number.\n");
  391. X                return;
  392. X            }
  393. X            ship->merchant = j;
  394. X        }
  395. X    } else if (match(args[2], "speed")) {
  396. X        if (speed_rating(ship)) {
  397. X            j = atoi(args[3]);
  398. X            if (j < 0) {
  399. X                notify(Playernum, Governor, "Specify a positive speed.\n");
  400. X                return;
  401. X            } else {
  402. X                if (j > speed_rating(ship))
  403. X                    j = speed_rating(ship);
  404. X                ship->speed = j;
  405. X            }
  406. X        } else {
  407. X            notify(Playernum, Governor, "This ship does not have a speed rating.\n");
  408. X            return;
  409. X        }
  410. X    } else if (match(args[2], "salvo")) {
  411. X        if (can_bombard(ship)) {
  412. X            j = atoi(args[3]);
  413. X            if (j < 0) {
  414. X                notify(Playernum, Governor, "Specify a positive number of guns.\n");
  415. X                return;
  416. X            } else {
  417. X                if (ship->guns == PRIMARY && j > ship->primary)
  418. X                    j = ship->primary;
  419. X                else if (ship->guns == SECONDARY && j > ship->secondary)
  420. X                    j = ship->secondary;
  421. X                else if (ship->guns == NONE)
  422. X                    j = 0;
  423. X
  424. X                ship->retaliate = j;
  425. X            }
  426. X        } else {
  427. X            notify(Playernum, Governor, "This ship cannot be set to retaliate.\n");
  428. X            return;
  429. X        }
  430. X    } else if (match(args[2], "primary")) {
  431. X        if (ship->primary) {
  432. X            if (argn < 4) {
  433. X                ship->guns = PRIMARY;
  434. X                if (ship->retaliate > ship->primary)
  435. X                    ship->retaliate = ship->primary;
  436. X            } else {
  437. X                j = atoi(args[3]);
  438. X                if (j < 0) {
  439. X                    notify(Playernum, Governor, "Specify a nonnegative number of guns.\n");
  440. X                    return;
  441. X                } else {
  442. X                    if (j > ship->primary)
  443. X                        j = ship->primary;
  444. X                    ship->retaliate = j;
  445. X                    ship->guns = PRIMARY;
  446. X                }
  447. X            }
  448. X        } else {
  449. X            notify(Playernum, Governor, "This ship does not have primary guns.\n");
  450. X            return;
  451. X        }
  452. X    } else if (match(args[2], "secondary")) {
  453. X        if (ship->secondary) {
  454. X            if (argn < 4) {
  455. X                ship->guns = SECONDARY;
  456. X                if (ship->retaliate > ship->secondary)
  457. X                    ship->retaliate = ship->secondary;
  458. X            } else {
  459. X                j = atoi(args[3]);
  460. X                if (j < 0) {
  461. X                    notify(Playernum, Governor, "Specify a nonnegative number of guns.\n");
  462. X                    return;
  463. X                } else {
  464. X                    if (j > ship->secondary)
  465. X                        j = ship->secondary;
  466. X                    ship->retaliate = j;
  467. X                    ship->guns = SECONDARY;
  468. X                }
  469. X            }
  470. X        } else {
  471. X            notify(Playernum, Governor, "This ship does not have secondary guns.\n");
  472. X            return;
  473. X        }
  474. X    } else if (match(args[2], "explosive")) {
  475. X        switch (ship->type) {
  476. X        case STYPE_MINE:
  477. X        case OTYPE_GR:
  478. X            ship->mode = 0;
  479. X            break;
  480. X        default:
  481. X            return;
  482. X        }
  483. X    } else if (match(args[2], "radiative")) {
  484. X        switch (ship->type) {
  485. X        case STYPE_MINE:
  486. X        case OTYPE_GR:
  487. X            ship->mode = 1;
  488. X            break;
  489. X        default:
  490. X            return;
  491. X        }
  492. X    } else if (match(args[2], "move")) {
  493. X        if ((ship->type == OTYPE_TERRA) || (ship->type == OTYPE_PLOW)) {
  494. X            i = 0;
  495. X            while (args[3][i]) {
  496. X                /*
  497. X                 * Make sure the list of moves is short
  498. X                 * enough.
  499. X                 */
  500. X                if (i == SHIP_NAMESIZE - 1) {
  501. X                    sprintf(buf, "Warning: that is more than %d moves.\n", SHIP_NAMESIZE - 1);
  502. X                    notify(Playernum, Governor, buf);
  503. X                    notify(Playernum, Governor, "These move orders have been truncated.\n");
  504. X                    args[3][i] = '\0';
  505. X                    break;
  506. X                }
  507. X                /* Make sure this move is OK. */
  508. X                if ((args[3][i] == 'c') || (args[3][i] == 's')) {
  509. X                    if ((i == 0) && (args[3][0] == 'c')) {
  510. X                        notify(Playernum, Governor, "Cycling move orders can not be empty!\n");
  511. X                        return;
  512. X                    }
  513. X                    if (args[3][i + 1]) {
  514. X                        sprintf(buf, "Warning: '%c' should be the last character in the move order.\n", args[3][i]);
  515. X                        notify(Playernum, Governor, buf);
  516. X                        notify(Playernum, Governor, "These move orders have been truncated.\n");
  517. X                        args[3][++i] = '\0';
  518. X                        break;
  519. X                    }
  520. X                } else if ((args[3][i] < '1') || ('9' < args[3][i])) {
  521. X                    sprintf(buf, "'%c' is not a valid move direction.\n", args[3][i]);
  522. X                    notify(Playernum, Governor, buf);
  523. X                    return;
  524. X                }
  525. X                i++;
  526. X            }
  527. X            if (i == 0)    /* The move list might be empty.. */
  528. X                strcpy(ship->class, "5");
  529. X            else
  530. X                strcpy(ship->class, args[3]);
  531. X            /*
  532. X             * This is the index keeping track of which order in
  533. X             * class is next.
  534. X             */
  535. X            ship->special.terraform.index = 0;
  536. X        } else {
  537. X            notify(Playernum, Governor, "That ship is not a terraformer or a space plow.\n");
  538. X            return;
  539. X        }
  540. X    } else if (match(args[2], "trigger")) {
  541. X        if (ship->type == STYPE_MINE) {
  542. X            if (atoi(args[3]) < 0)
  543. X                ship->special.trigger.radius = 0;
  544. X            else
  545. X                ship->special.trigger.radius = atoi(args[3]);
  546. X        } else {
  547. X            notify(Playernum, Governor, "This ship cannot be assigned a trigger radius.\n");
  548. X            return;
  549. X        }
  550. X    } else if (match(args[2], "transport")) {
  551. X        if (ship->type == OTYPE_TRANSDEV) {
  552. X            ship->special.transport.target = atoi(args[3]);
  553. X            if (ship->special.transport.target == ship->number) {
  554. X                notify(Playernum, Governor, "A transporter cannot transport to itself.");
  555. X                ship->special.transport.target = 0;
  556. X            } else {
  557. X                sprintf(buf, "Target ship is %d.\n", ship->special.transport.target);
  558. X                notify(Playernum, Governor, buf);
  559. X            }
  560. X        } else {
  561. X            notify(Playernum, Governor, "This ship is not a transporter.\n");
  562. X            return;
  563. X        }
  564. X    } else if (match(args[2], "aim")) {
  565. X        if (can_aim(ship)) {
  566. X            if (ship->type == OTYPE_GTELE || ship->type == OTYPE_TRACT
  567. X                || ship->fuel >= FUEL_MANEUVER) {
  568. X                if (ship->type == STYPE_MIRROR && ship->docked) {
  569. X                    sprintf(buf, "docked; use undock or launch first.\n");
  570. X                    notify(Playernum, Governor, buf);
  571. X                    return;
  572. X                }
  573. X                pl = Getplace(Playernum, Governor, args[3], 1);
  574. X                if (pl.err) {
  575. X                    notify(Playernum, Governor, "Error in destination.\n");
  576. X                    return;
  577. X                } else {
  578. X                    ship->special.aimed_at.level = pl.level;
  579. X                    ship->special.aimed_at.pnum = pl.pnum;
  580. X                    ship->special.aimed_at.snum = pl.snum;
  581. X                    ship->special.aimed_at.shipno = pl.shipno;
  582. X                    if (ship->type != OTYPE_TRACT &&
  583. X                        ship->type != OTYPE_GTELE)
  584. X                        use_fuel(ship, FUEL_MANEUVER);
  585. X                    if (ship->type == OTYPE_GTELE ||
  586. X                        ship->type == OTYPE_STELE)
  587. X                        mk_expl_aimed_at(Playernum, Governor, ship);
  588. X                    sprintf(buf, "Aimed at %s\n", prin_aimed_at(Playernum, Governor, ship));
  589. X                    notify(Playernum, Governor, buf);
  590. X                }
  591. X            } else {
  592. X                sprintf(buf, "Not enough maneuvering fuel (%.2f).\n", FUEL_MANEUVER);
  593. X                notify(Playernum, Governor, buf);
  594. X                return;
  595. X            }
  596. X        } else {
  597. X            notify(Playernum, Governor, "You can't aim that kind of ship.\n");
  598. X            return;
  599. X        }
  600. X    } else if (match(args[2], "intensity")) {
  601. X        if (ship->type == STYPE_MIRROR) {
  602. X            ship->special.aimed_at.intensity = MAX(0, MIN(100, atoi(args[3])));
  603. X        }
  604. X    } else if (match(args[2], "on")) {
  605. X        if (!has_switch(ship)) {
  606. X            notify(Playernum, Governor, "This ship does not have an on/off setting.\n");
  607. X            return;
  608. X        }
  609. X        if (ship->damage && ship->type != OTYPE_FACTORY) {
  610. X            notify(Playernum, Governor, "Damaged ships cannot be activated.\n");
  611. X            return;
  612. X        }
  613. X        if (ship->on) {
  614. X            notify(Playernum, Governor, "This ship is already activated.\n");
  615. X            return;
  616. X        }
  617. X        if (ship->type == OTYPE_FACTORY) {
  618. X            unsigned int    oncost;
  619. X            if (ship->whatorbits == LEVEL_SHIP) {
  620. X                shiptype       *s2;
  621. X                int             hangerneeded;
  622. X
  623. X                (void) getship(&s2, (int) ship->destshipno);
  624. X                if (s2->type == STYPE_HABITAT) {
  625. X                    oncost = HAB_FACT_ON_COST * ship->build_cost;
  626. X                    if (s2->resource < oncost) {
  627. X                        sprintf(buf, "You don't have %d resources on Habitat #%d to activate this factory.\n",
  628. X                          oncost, ship->destshipno);
  629. X                        notify(Playernum, Governor, buf);
  630. X                        free(s2);
  631. X                        return;
  632. X                    }
  633. X                    hangerneeded = (1 + (int) (HAB_FACT_SIZE * (double) ship_size(ship))) -
  634. X                        ((s2->max_hanger - s2->hanger) + ship->size);
  635. X                    if (hangerneeded > 0) {
  636. X                        sprintf(buf, "Not enough hanger space free on Habitat #%d. Need %d more.\n",
  637. X                            ship->destshipno, hangerneeded);
  638. X                        notify(Playernum, Governor, buf);
  639. X                        free(s2);
  640. X                        return;
  641. X                    }
  642. X                    s2->resource -= oncost;
  643. X                    s2->hanger -= ship->size;
  644. X                    ship->size = 1 + (int) (HAB_FACT_SIZE * (double) ship_size(ship));
  645. X                    s2->hanger += ship->size;
  646. X                    putship(s2);
  647. X                    free(s2);
  648. X                } else {
  649. X                    notify(Playernum, Governor, "The factory is currently being transported.\n");
  650. X                    free(s2);
  651. X                    return;
  652. X                }
  653. X            } else if (!landed(ship)) {
  654. X                notify(Playernum, Governor, "You cannot activate the factory here.\n");
  655. X                return;
  656. X            } else {
  657. X                getplanet(&planet, (int) ship->deststar, (int) ship->destpnum);
  658. X                oncost = 2 * ship->build_cost;
  659. X                if (planet->info[Playernum - 1].resource < oncost) {
  660. X                    sprintf(buf, "You don't have %d resources on the planet to activate this factory.\n",
  661. X                        oncost);
  662. X                    notify(Playernum, Governor, buf);
  663. X                    free(planet);
  664. X                    return;
  665. X                } else {
  666. X                    planet->info[Playernum - 1].resource -= oncost;
  667. X                    putplanet(planet, (int) ship->deststar, (int) ship->destpnum);
  668. X                    free(planet);
  669. X                }
  670. X            }
  671. X            sprintf(buf, "Factory activated at a cost of %d resources.\n", oncost);
  672. X            notify(Playernum, Governor, buf);
  673. X        }
  674. X        ship->on = 1;
  675. X    } else if (match(args[2], "off")) {
  676. X        if (ship->type == OTYPE_FACTORY && ship->on) {
  677. X            notify(Playernum, Governor, "You can't deactivate a factory once it's online. Consider using 'scrap'.\n");
  678. X            return;
  679. X        }
  680. X        ship->on = 0;
  681. X    }
  682. X    ship->notified = 0;
  683. X    putship(ship);
  684. X}
  685. X
  686. Xchar           *
  687. Xprin_aimed_at(int Playernum, int Governor, shiptype * ship)
  688. X{
  689. X    placetype       targ;
  690. X
  691. X    targ.level = ship->special.aimed_at.level;
  692. X    targ.snum = ship->special.aimed_at.snum;
  693. X    targ.pnum = ship->special.aimed_at.pnum;
  694. X    targ.shipno = ship->special.aimed_at.shipno;
  695. X    return Dispplace(Playernum, Governor, &targ);
  696. X}
  697. X
  698. Xchar           *
  699. Xprin_ship_dest(int Playernum, int Governor, shiptype * ship)
  700. X{
  701. X    placetype       dest;
  702. X
  703. X    dest.level = ship->whatdest;
  704. X    dest.snum = ship->deststar;
  705. X    dest.pnum = ship->destpnum;
  706. X    dest.shipno = ship->destshipno;
  707. X    return Dispplace(Playernum, Governor, &dest);
  708. X}
  709. X
  710. X
  711. X/*
  712. X * mark wherever the ship is aimed at, as explored by the owning player.
  713. X */
  714. Xvoid 
  715. Xmk_expl_aimed_at(int Playernum, int Governor, shiptype * s)
  716. X{
  717. X    double          dist;
  718. X    startype       *str;
  719. X    planettype     *p;
  720. X    double          xf, yf;
  721. X
  722. X    str = Stars[s->special.aimed_at.snum];
  723. X
  724. X    xf = s->xpos;
  725. X    yf = s->ypos;
  726. X
  727. X    switch (s->special.aimed_at.level) {
  728. X    case LEVEL_UNIV:
  729. X        sprintf(buf, "There is nothing out here to aim at.");
  730. X        notify(Playernum, Governor, buf);
  731. X        break;
  732. X    case LEVEL_STAR:
  733. X        sprintf(buf, "Star %s ", prin_aimed_at(Playernum, Governor, s));
  734. X        notify(Playernum, Governor, buf);
  735. X        if ((dist = sqrt(Distsq(xf, yf, str->xpos, str->ypos)))
  736. X            <= tele_range((int) s->type, s->tech)) {
  737. X            getstar(&str, (int) s->special.aimed_at.snum);
  738. X            setbit(str->explored, Playernum);
  739. X            putstar(str, (int) s->special.aimed_at.snum);
  740. X            sprintf(buf, "Surveyed, distance %g.\n", dist);
  741. X            notify(Playernum, Governor, buf);
  742. X            free(str);
  743. X        } else {
  744. X            sprintf(buf, "Too far to see (%g, max %g).\n",
  745. X                dist, tele_range((int) s->type, s->tech));
  746. X            notify(Playernum, Governor, buf);
  747. X        }
  748. X        break;
  749. X    case LEVEL_PLAN:
  750. X        sprintf(buf, "Planet %s ", prin_aimed_at(Playernum, Governor, s));
  751. X        notify(Playernum, Governor, buf);
  752. X        getplanet(&p, (int) s->special.aimed_at.snum, (int) s->special.aimed_at.pnum);
  753. X        if ((dist = sqrt(Distsq(xf, yf, str->xpos + p->xpos, str->ypos + p->ypos)))
  754. X            <= tele_range((int) s->type, s->tech)) {
  755. X            setbit(str->explored, Playernum);
  756. X            p->info[Playernum - 1].explored = 1;
  757. X            putplanet(p, (int) s->special.aimed_at.snum, (int) s->special.aimed_at.pnum);
  758. X            sprintf(buf, "Surveyed, distance %g.\n", dist);
  759. X            notify(Playernum, Governor, buf);
  760. X        } else {
  761. X            sprintf(buf, "Too far to see (%g, max %g).\n",
  762. X                dist, tele_range((int) s->type, s->tech));
  763. X            notify(Playernum, Governor, buf);
  764. X        }
  765. X        free(p);
  766. X        break;
  767. X    case LEVEL_SHIP:
  768. X        sprintf(buf, "You can't see anything of use there.\n");
  769. X        notify(Playernum, Governor, buf);
  770. X        break;
  771. X    }
  772. X}
  773. X
  774. Xvoid 
  775. XDispOrdersHeader(int Playernum, int Governor)
  776. X{
  777. X    notify(Playernum, Governor, "    #       name       sp orbits     destin     options\n");
  778. X}
  779. X
  780. Xvoid 
  781. XDispOrders(int Playernum, int Governor, shiptype * ship)
  782. X{
  783. X    double          distfac;
  784. X#ifdef THRESHLOADING
  785. X    int                i;
  786. X#endif
  787. X
  788. X    if (ship->owner != Playernum || !authorized(Governor, ship)
  789. X        || !ship->alive)
  790. X        return;
  791. X
  792. X    if (ship->docked)
  793. X        if (ship->whatdest == LEVEL_SHIP)
  794. X            sprintf(temp, "D#%d", ship->destshipno);
  795. X        else
  796. X            sprintf(temp, "L%2d,%-2d", ship->land_x, ship->land_y);
  797. X    else
  798. X        strcpy(temp, prin_ship_dest(Playernum, Governor, ship));
  799. X
  800. X    sprintf(buf, "%5d %c %14.14s %c%1u %-10s %-10.10s ",
  801. X        ship->number, Shipltrs[ship->type], ship->name,
  802. X        ship->hyper_drive.has ? (ship->mount ? (ship->mounted ? '+' : '-') : '*') : ' ', 
  803. X        ship->speed,
  804. X        Dispshiploc_brief(ship),
  805. X        temp);
  806. X
  807. X    if (ship->hyper_drive.on) {
  808. X        sprintf(temp, "/jump %s %d", (ship->hyper_drive.ready ? "ready" : "charging"),
  809. X            ship->hyper_drive.charge);
  810. X        strcat(buf, temp);
  811. X    }
  812. X    if (ship->protect.self) {
  813. X        sprintf(temp, "/retal");
  814. X        strcat(buf, temp);
  815. X    }
  816. X    if (ship->guns == PRIMARY) {
  817. X        switch (ship->primtype) {
  818. X        case LIGHT:
  819. X            sprintf(temp, "/lgt primary");
  820. X            break;
  821. X        case MEDIUM:
  822. X            sprintf(temp, "/med primary");
  823. X            break;
  824. X        case HEAVY:
  825. X            sprintf(temp, "/hvy primary");
  826. X            break;
  827. X        default:
  828. X            sprintf(temp, "/none");
  829. X        }
  830. X        strcat(buf, temp);
  831. X    } else if (ship->guns == SECONDARY) {
  832. X        switch (ship->sectype) {
  833. X        case LIGHT:
  834. X            sprintf(temp, "/lgt secondary");
  835. X            break;
  836. X        case MEDIUM:
  837. X            sprintf(temp, "/med secndry");
  838. X            break;
  839. X        case HEAVY:
  840. X            sprintf(temp, "/hvy secndry");
  841. X            break;
  842. X        default:
  843. X            sprintf(temp, "/none");
  844. X        }
  845. X        strcat(buf, temp);
  846. X    }
  847. X    if (ship->fire_laser) {
  848. X        sprintf(temp, "/laser %d", ship->fire_laser);
  849. X        strcat(buf, temp);
  850. X    }
  851. X    if (ship->focus)
  852. X        strcat(buf, "/focus");
  853. X
  854. X    if (ship->retaliate) {
  855. X        sprintf(temp, "/salvo %d", ship->retaliate);
  856. X        strcat(buf, temp);
  857. X    }
  858. X    if (ship->protect.planet)
  859. X        strcat(buf, "/defense");
  860. X    if (ship->protect.on) {
  861. X        sprintf(temp, "/prot %d", ship->protect.ship);
  862. X        strcat(buf, temp);
  863. X    }
  864. X    if (ship->navigate.on) {
  865. X        sprintf(temp, "/nav %d (%d)", ship->navigate.bearing, ship->navigate.turns);
  866. X        strcat(buf, temp);
  867. X    }
  868. X    if (ship->merchant) {
  869. X        sprintf(temp, "/merchant %d", ship->merchant);
  870. X        strcat(buf, temp);
  871. X    }
  872. X    if (has_switch(ship)) {
  873. X        if (ship->on)
  874. X            strcat(buf, "/on");
  875. X        else
  876. X            strcat(buf, "/off");
  877. X    }
  878. X    if (ship->protect.evade)
  879. X        strcat(buf, "/evade");
  880. X    if (ship->bombard)
  881. X        strcat(buf, "/bomb");
  882. X    if (ship->type == STYPE_MINE || ship->type == OTYPE_GR) {
  883. X        if (ship->mode)
  884. X            strcat(buf, "/radiate");
  885. X        else
  886. X            strcat(buf, "/explode");
  887. X    }
  888. X    if (ship->type == OTYPE_TERRA || ship->type == OTYPE_PLOW) {
  889. X        int             i;
  890. X        sprintf(temp, "/move %s", &(ship->class[ship->special.terraform.index]));
  891. X        if (temp[i = (strlen(temp) - 1)] == 'c') {
  892. X            char            c = ship->class[ship->special.terraform.index];
  893. X            ship->class[ship->special.terraform.index] = '\0';
  894. X            sprintf(temp + i, "%sc", ship->class);
  895. X            ship->class[ship->special.terraform.index] = c;
  896. X        }
  897. X        strcat(buf, temp);
  898. X    }
  899. X    if (ship->type == STYPE_MISSILE && ship->whatdest == LEVEL_PLAN) {
  900. X        if (ship->special.impact.scatter)
  901. X            strcat(buf, "/scatter");
  902. X        else {
  903. X            sprintf(temp, "/impact %d,%d",
  904. X                ship->special.impact.x, ship->special.impact.y);
  905. X            strcat(buf, temp);
  906. X        }
  907. X    }
  908. X    if (ship->type == STYPE_MINE) {
  909. X        sprintf(temp, "/trigger %d", ship->special.trigger.radius);
  910. X        strcat(buf, temp);
  911. X    }
  912. X    if (ship->type == OTYPE_TRANSDEV) {
  913. X        sprintf(temp, "/target %d", ship->special.transport.target);
  914. X        strcat(buf, temp);
  915. X    }
  916. X    if (ship->type == STYPE_MIRROR) {
  917. X        sprintf(temp, "/aim %s/int %d", prin_aimed_at(Playernum, Governor, ship),
  918. X            ship->special.aimed_at.intensity);
  919. X        strcat(buf, temp);
  920. X    }
  921. X#ifdef AUTOSCRAP
  922. X    if (ship->autoscrap) {
  923. X        sprintf(temp, "%s", "/autoscrap");
  924. X        strcat(buf, temp);
  925. X    } 
  926. X#endif 
  927. X#ifdef THRESHLOADING
  928. X    for (i=0;i<=TH_CRYSTALS;i++) {
  929. X        if (ship->threshload[i]) {
  930. X        char c;
  931. X            if (i==TH_RESOURCE) 
  932. X                c = 'r';
  933. X            else if (i==TH_DESTRUCT) 
  934. X                c = 'd';
  935. X            else if (i==TH_FUEL) 
  936. X                c = 'f';
  937. X            else
  938. X                 c = 'x';
  939. X        sprintf(temp,"/%c%d", c, ship->threshload[i]);
  940. X        strcat(buf,temp);
  941. X        }
  942. X    }
  943. X#endif 
  944. X
  945. X    strcat(buf, "\n");
  946. X    notify(Playernum, Governor, buf);
  947. X    /*
  948. X     * if hyper space is on estimate how much fuel it will cost to get to
  949. X     * the destination
  950. X     */
  951. X    if (ship->hyper_drive.on) {
  952. X        double          dist, fuse;
  953. X
  954. X        dist = sqrt(Distsq(ship->xpos, ship->ypos, Stars[ship->deststar]->xpos,
  955. X                   Stars[ship->deststar]->ypos));
  956. X        distfac = HYPER_DIST_FACTOR * (ship->tech + 100.0);
  957. X        if (ship->mounted && dist > distfac) {
  958. X            fuse = HYPER_DRIVE_FUEL_USE * sqrt(ship->mass)
  959. X                * (dist / distfac);
  960. X        } else {
  961. X            fuse = HYPER_DRIVE_FUEL_USE * sqrt(ship->mass)
  962. X                * (dist / distfac) * (dist / distfac);
  963. X        }
  964. X
  965. X        sprintf(buf, "  *** distance %.0f - jump will cost %.1ff ***\n", dist, fuse);
  966. X        notify(Playernum, Governor, buf);
  967. X        if (ship->max_fuel < fuse)
  968. X            notify(Playernum, Governor, "Your ship cannot carry enough fuel to do this jump.\n");
  969. X    }
  970. X}
  971. X
  972. Xvoid 
  973. Xroute(int Playernum, int Governor, int APcount)
  974. X{
  975. X    int             i, x, y;
  976. X    unsigned char   star, planet, load, unload;
  977. X    char           *c;
  978. X    planettype     *p;
  979. X    placetype       where;
  980. X
  981. X    if (Dir[Playernum - 1][Governor].level != LEVEL_PLAN) {
  982. X        notify(Playernum, Governor, "You have to 'cs' to a planet to examine routes.\n");
  983. X        return;
  984. X    }
  985. X    getplanet(&p, Dir[Playernum - 1][Governor].snum, Dir[Playernum - 1][Governor].pnum);
  986. X    if (argn == 1) {    /* display all shipping routes that are
  987. X                 * active */
  988. X        for (i = 1; i <= MAX_ROUTES; i++)
  989. X            if (p->info[Playernum - 1].route[i - 1].set) {
  990. X                star = p->info[Playernum - 1].route[i - 1].dest_star;
  991. X                planet = p->info[Playernum - 1].route[i - 1].dest_planet;
  992. X                load = p->info[Playernum - 1].route[i - 1].load;
  993. X                unload = p->info[Playernum - 1].route[i - 1].unload;
  994. X                sprintf(buf, "%2d  land %2d,%2d   ", i,
  995. X                      p->info[Playernum - 1].route[i - 1].x,
  996. X                     p->info[Playernum - 1].route[i - 1].y);
  997. X                strcat(buf, "load: ");
  998. X                if (Fuel(load))
  999. X                    strcat(buf, "f");
  1000. X                else
  1001. X                    strcat(buf, " ");
  1002. X                if (Destruct(load))
  1003. X                    strcat(buf, "d");
  1004. X                else
  1005. X                    strcat(buf, " ");
  1006. X                if (Resources(load))
  1007. X                    strcat(buf, "r");
  1008. X                else
  1009. X                    strcat(buf, " ");
  1010. X                if (Crystals(load))
  1011. X                    strcat(buf, "x");
  1012. X                strcat(buf, " ");
  1013. X
  1014. X                strcat(buf, "  unload: ");
  1015. X                if (Fuel(unload))
  1016. X                    strcat(buf, "f");
  1017. X                else
  1018. X                    strcat(buf, " ");
  1019. X                if (Destruct(unload))
  1020. X                    strcat(buf, "d");
  1021. X                else
  1022. X                    strcat(buf, " ");
  1023. X                if (Resources(unload))
  1024. X                    strcat(buf, "r");
  1025. X                else
  1026. X                    strcat(buf, " ");
  1027. X                if (Crystals(unload))
  1028. X                    strcat(buf, "x");
  1029. X                else
  1030. X                    strcat(buf, " ");
  1031. X                sprintf(temp, "  -> %s/%s\n",
  1032. X                    Stars[star]->name, Stars[star]->pnames[planet]);
  1033. X                strcat(buf, temp);
  1034. X                notify(Playernum, Governor, buf);
  1035. X            }
  1036. X        notify(Playernum, Governor, "Done.\n");
  1037. X        free(p);
  1038. X        return;
  1039. X    } else if (argn == 2) {
  1040. X        sscanf(args[1], "%d", &i);
  1041. X        if (i > MAX_ROUTES || i < 1) {
  1042. X            notify(Playernum, Governor, "Bad route number.\n");
  1043. X            free(p);
  1044. X            return;
  1045. X        }
  1046. X        if (p->info[Playernum - 1].route[i - 1].set) {
  1047. X            star = p->info[Playernum - 1].route[i - 1].dest_star;
  1048. X            planet = p->info[Playernum - 1].route[i - 1].dest_planet;
  1049. X            load = p->info[Playernum - 1].route[i - 1].load;
  1050. X            unload = p->info[Playernum - 1].route[i - 1].unload;
  1051. X            sprintf(buf, "%2d  land %2d,%2d   ", i,
  1052. X                p->info[Playernum - 1].route[i - 1].x,
  1053. X                p->info[Playernum - 1].route[i - 1].y);
  1054. X            if (load) {
  1055. X                sprintf(temp, "load: ");
  1056. X                strcat(buf, temp);
  1057. X                if (Fuel(load))
  1058. X                    strcat(buf, "f");
  1059. X                if (Destruct(load))
  1060. X                    strcat(buf, "d");
  1061. X                if (Resources(load))
  1062. X                    strcat(buf, "r");
  1063. X                if (Crystals(load))
  1064. X                    strcat(buf, "x");
  1065. X            }
  1066. X            if (unload) {
  1067. X                sprintf(temp, "  unload: ");
  1068. X                strcat(buf, temp);
  1069. X                if (Fuel(unload))
  1070. X                    strcat(buf, "f");
  1071. X                if (Destruct(unload))
  1072. X                    strcat(buf, "d");
  1073. X                if (Resources(unload))
  1074. X                    strcat(buf, "r");
  1075. X                if (Crystals(unload))
  1076. X                    strcat(buf, "x");
  1077. X            }
  1078. X            sprintf(temp, "  ->  %s/%s\n",
  1079. X                Stars[star]->name, Stars[star]->pnames[planet]);
  1080. X            strcat(buf, temp);
  1081. X            notify(Playernum, Governor, buf);
  1082. X        }
  1083. X        notify(Playernum, Governor, "Done.\n");
  1084. X        free(p);
  1085. X        return;
  1086. X    } else if (argn == 3) {
  1087. X        sscanf(args[1], "%d", &i);
  1088. X        if (i > MAX_ROUTES || i < 1) {
  1089. X            notify(Playernum, Governor, "Bad route number.\n");
  1090. X            free(p);
  1091. X            return;
  1092. X        }
  1093. X        if (match(args[2], "activate"))
  1094. X            p->info[Playernum - 1].route[i - 1].set = 1;
  1095. X        else if (match(args[2], "deactivate"))
  1096. X            p->info[Playernum - 1].route[i - 1].set = 0;
  1097. X        else {
  1098. X            where = Getplace(Playernum, Governor, args[2], 1);
  1099. X            if (!where.err) {
  1100. X                if (where.level != LEVEL_PLAN) {
  1101. X                    notify(Playernum, Governor, "You have to designate a planet.\n");
  1102. X                    free(p);
  1103. X                    return;
  1104. X                }
  1105. X                p->info[Playernum - 1].route[i - 1].dest_star = where.snum;
  1106. X                p->info[Playernum - 1].route[i - 1].dest_planet = where.pnum;
  1107. X                notify(Playernum, Governor, "Set.\n");
  1108. X            } else {
  1109. X                notify(Playernum, Governor, "Illegal destination.\n");
  1110. X                free(p);
  1111. X                return;
  1112. X            }
  1113. X        }
  1114. X    } else {
  1115. X        sscanf(args[1], "%d", &i);
  1116. X        if (i > MAX_ROUTES || i < 1) {
  1117. X            notify(Playernum, Governor, "Bad route number.\n");
  1118. X            free(p);
  1119. X            return;
  1120. X        }
  1121. X        if (match(args[2], "land")) {
  1122. X            sscanf(args[3], "%d,%d", &x, &y);
  1123. X            if (x < 0 || x > p->Maxx - 1 || y < 0 || y > p->Maxy - 1) {
  1124. X                notify(Playernum, Governor, "Bad sector coordinates.\n");
  1125. X                free(p);
  1126. X                return;
  1127. X            }
  1128. X            p->info[Playernum - 1].route[i - 1].x = x;
  1129. X            p->info[Playernum - 1].route[i - 1].y = y;
  1130. X        } else if (match(args[2], "load")) {
  1131. X            p->info[Playernum - 1].route[i - 1].load = 0;
  1132. X            c = args[3];
  1133. X            while (*c) {
  1134. X                if (*c == 'f')
  1135. X                    p->info[Playernum - 1].route[i - 1].load |= M_FUEL;
  1136. X                if (*c == 'd')
  1137. X                    p->info[Playernum - 1].route[i - 1].load |= M_DESTRUCT;
  1138. X                if (*c == 'r')
  1139. X                    p->info[Playernum - 1].route[i - 1].load |= M_RESOURCES;
  1140. X                if (*c == 'x')
  1141. X                    p->info[Playernum - 1].route[i - 1].load |= M_CRYSTALS;
  1142. X                c++;
  1143. X            }
  1144. X        } else if (match(args[2], "unload")) {
  1145. X            p->info[Playernum - 1].route[i - 1].unload = 0;
  1146. X            c = args[3];
  1147. X            while (*c) {
  1148. X                if (*c == 'f')
  1149. X                    p->info[Playernum - 1].route[i - 1].unload |= M_FUEL;
  1150. X                if (*c == 'd')
  1151. X                    p->info[Playernum - 1].route[i - 1].unload |= M_DESTRUCT;
  1152. X                if (*c == 'r')
  1153. X                    p->info[Playernum - 1].route[i - 1].unload |= M_RESOURCES;
  1154. X                if (*c == 'x')
  1155. X                    p->info[Playernum - 1].route[i - 1].unload |= M_CRYSTALS;
  1156. X                c++;
  1157. X            }
  1158. X        } else {
  1159. X            notify(Playernum, Governor, "What are you trying to do?\n");
  1160. X            free(p);
  1161. X            return;
  1162. X        }
  1163. X        notify(Playernum, Governor, "Set.\n");
  1164. X    }
  1165. X    putplanet(p, Dir[Playernum - 1][Governor].snum, Dir[Playernum - 1][Governor].pnum);
  1166. X    free(p);
  1167. X}
  1168. END_OF_FILE
  1169. if test 32144 -ne `wc -c <'user/order.c'`; then
  1170.     echo shar: \"'user/order.c'\" unpacked with wrong size!
  1171. fi
  1172. # end of 'user/order.c'
  1173. fi
  1174. if test -f 'user/shootblast.c' -a "${1}" != "-c" ; then 
  1175.   echo shar: Will not clobber existing file \"'user/shootblast.c'\"
  1176. else
  1177. echo shar: Extracting \"'user/shootblast.c'\" \(18678 characters\)
  1178. sed "s/^X//" >'user/shootblast.c' <<'END_OF_FILE'
  1179. X#include <math.h>
  1180. X
  1181. X#include "GB_copyright.h"
  1182. X#define EXTERN extern
  1183. X#include "vars.h"
  1184. X#include "ships.h"
  1185. X#include "races.h"
  1186. X#include "power.h"
  1187. X#include "buffers.h"
  1188. X
  1189. X
  1190. Xextern int      Defensedata[];
  1191. X
  1192. Xint             hit_probability;
  1193. Xdouble          penetration_factor;
  1194. X
  1195. Xint 
  1196. Xshoot_ship_to_ship(shiptype *, shiptype *, int, int, int, char *,
  1197. X           char *);
  1198. X#ifdef DEFENSE
  1199. Xint 
  1200. Xshoot_planet_to_ship(racetype *, planettype *, shiptype *, int,
  1201. X             char *, char *);
  1202. X#endif
  1203. Xint 
  1204. Xshoot_ship_to_planet(shiptype *, planettype *, int, int, int, int, int,
  1205. X             int, char *, char *);
  1206. Xint             do_radiation(shiptype *, double, int, int, char *, char *);
  1207. Xint 
  1208. Xdo_damage(int, shiptype *, double, int, int, int, int, double, char *,
  1209. X      char *);
  1210. Xvoid            ship_disposition(shiptype *, int *, int *, int *);
  1211. Xint             CEW_hit(double, int);
  1212. Xint 
  1213. XNum_hits(double, int, int, double, int, int, int, int, int, int, int,
  1214. X     int);
  1215. Xint             hit_odds(double, int *, double, int, int, int, int, int, int, int, int);
  1216. Xint             cew_hit_odds(double, int);
  1217. Xdouble          gun_range(racetype *, shiptype *, int);
  1218. Xdouble          tele_range(int, double);
  1219. Xint             current_caliber(shiptype *);
  1220. Xvoid            do_critical_hits(int, shiptype *, int *, int *, int, char *);
  1221. Xvoid            do_collateral(shiptype *, int, int *, int *, int *, int *);
  1222. Xint             getdefense(shiptype *);
  1223. Xdouble          p_factor(double, double);
  1224. Xint             planet_guns(int);
  1225. Xvoid            mutate_sector(sectortype *);
  1226. X#include "proto.h"
  1227. X
  1228. Xint 
  1229. Xshoot_ship_to_ship(shiptype * from, shiptype * to, int strength, int cew,
  1230. X           int ignore, char *long_msg, char *short_msg)
  1231. X{
  1232. X    double          range;
  1233. X    int             hits, casualties, casualties1, primgundamage, secgundamage;
  1234. X    int             penetrate, crithits, critdam, damage, defense;
  1235. X    double          dist, xfrom, yfrom, xto, yto;
  1236. X    int             focus, fevade, fspeed, fbody, tevade, tspeed, tbody,
  1237. X                    caliber;
  1238. X    char            weapon[32], damage_msg[1024];
  1239. X
  1240. X    range = 0.0;
  1241. X    casualties = 0;
  1242. X    casualties1 = 0;
  1243. X    primgundamage = 0;
  1244. X    secgundamage = 0;
  1245. X    hits = 0;
  1246. X    defense = 1;
  1247. X    penetrate = 0;
  1248. X    crithits = 0;
  1249. X    critdam = 0;
  1250. X    if (strength <= 0)
  1251. X        return -1;
  1252. X
  1253. X    if (!(from->alive || ignore) || !to->alive)
  1254. X        return -1;
  1255. X    if (from->whatorbits == LEVEL_SHIP || from->whatorbits == LEVEL_UNIV)
  1256. X        return -1;
  1257. X    if (to->whatorbits == LEVEL_SHIP || to->whatorbits == LEVEL_UNIV)
  1258. X        return -1;
  1259. X    if (from->storbits != to->storbits)
  1260. X        return -1;
  1261. X    if (has_switch(from) && !from->on)
  1262. X        return -1;
  1263. X
  1264. X    xfrom = from->xpos;
  1265. X    yfrom = from->ypos;
  1266. X
  1267. X    xto = to->xpos;
  1268. X    yto = to->ypos;
  1269. X    /* compute caliber */
  1270. X    caliber = current_caliber(from);
  1271. X
  1272. X    if (from->type == STYPE_MISSILE)    /* missiles hit at point
  1273. X                         * blank range */
  1274. X        dist = 0.0;
  1275. X    else {
  1276. X        dist = sqrt((double) Distsq(xfrom, yfrom, xto, yto));
  1277. X        if (from->type == STYPE_MINE) {    /* compute the effective
  1278. X                         * range */
  1279. X            dist *= dist / 200.0;    /* mines are very effective
  1280. X                         * inside 200 */
  1281. X        }
  1282. X    }
  1283. X    range = (double) dist;
  1284. X    if ((double) dist > gun_range((racetype *) NULL, from, 0))
  1285. X        return -1;
  1286. X    /* attack parameters */
  1287. X    ship_disposition(from, &fevade, &fspeed, &fbody);
  1288. X    ship_disposition(to, &tevade, &tspeed, &tbody);
  1289. X    defense = getdefense(to);
  1290. X
  1291. X    if (laser_on(from) && from->focus)
  1292. X        focus = 1;
  1293. X    else
  1294. X        focus = 0;
  1295. X
  1296. X    if (cew)
  1297. X        hits = strength * CEW_hit((double) dist, (int) from->cew_range);
  1298. X    else
  1299. X        hits = Num_hits((double) dist, focus, strength, from->tech, (int) from->damage,
  1300. X           fevade, tevade, fspeed, tspeed, tbody, caliber, defense);
  1301. X    /* CEW, destruct, lasers */
  1302. X    damage = 0;
  1303. X    if (from->mode) {
  1304. X        damage = do_radiation(to, from->tech, strength,
  1305. X                      hits, "radiation", damage_msg);
  1306. X        sprintf(short_msg, "%s: %s %s %s\n",
  1307. X            Dispshiploc(to), Ship(from),
  1308. X            to->alive ? "attacked" : "DESTROYED", Ship(to));
  1309. X        strcpy(long_msg, short_msg);
  1310. X        strcat(long_msg, damage_msg);
  1311. X    } else {
  1312. X        if (cew)
  1313. X            sprintf(weapon, "strength CEW");
  1314. X        else if (laser_on(from)) {
  1315. X            if (from->focus)
  1316. X                sprintf(weapon, "strength focused laser");
  1317. X            else
  1318. X                sprintf(weapon, "strength laser");
  1319. X        } else
  1320. X            switch (caliber) {
  1321. X            case LIGHT:
  1322. X                sprintf(weapon, "light guns");
  1323. X                break;
  1324. X            case MEDIUM:
  1325. X                sprintf(weapon, "medium guns");
  1326. X                break;
  1327. X            case HEAVY:
  1328. X                sprintf(weapon, "heavy guns");
  1329. X                break;
  1330. X            default:
  1331. X                sprintf(weapon, "pea-shooter");
  1332. X                return -1;
  1333. X            }
  1334. X
  1335. X        damage = do_damage((int) from->owner, to, (double) from->tech,
  1336. X                   strength, hits, defense,
  1337. X                caliber, (double) dist, weapon, damage_msg);
  1338. X        sprintf(short_msg, "%s: %s %s %s\n",
  1339. X            Dispshiploc(to), Ship(from),
  1340. X            to->alive ? "attacked" : "DESTROYED", Ship(to));
  1341. X        strcpy(long_msg, short_msg);
  1342. X        strcat(long_msg, damage_msg);
  1343. X    }
  1344. X    return damage;
  1345. X}
  1346. X
  1347. X#ifdef DEFENSE
  1348. Xint 
  1349. Xshoot_planet_to_ship(racetype * Race, planettype * p, shiptype * ship,
  1350. X             int strength, char *long_msg, char *short_msg)
  1351. X{
  1352. X    int             hits, casualties, casualties1, primgundamage, secgundamage;
  1353. X    int             evade, speed, body;
  1354. X    int             damage;
  1355. X    char            damage_msg[1024];
  1356. X
  1357. X    casualties = casualties1 = 0;
  1358. X    primgundamage = secgundamage = 0;
  1359. X    hits = 0;
  1360. X    if (strength <= 0)
  1361. X        return -1;
  1362. X    if (!ship->alive)
  1363. X        return -1;
  1364. X
  1365. X    if (ship->whatorbits != LEVEL_PLAN)
  1366. X        return -1;
  1367. X
  1368. X    ship_disposition(ship, &evade, &speed, &body);
  1369. X
  1370. X    hits = Num_hits(0.0, 0, strength, Race->tech, 0,
  1371. X            evade, 0, speed, 0, body, MEDIUM, 1);
  1372. X
  1373. X    damage = do_damage(Race->Playernum, ship,
  1374. X               Race->tech, strength, hits, 0,
  1375. X               MEDIUM, 0.0, "medium guns", damage_msg);
  1376. X    sprintf(short_msg, "%s [%d] %s %s\n",
  1377. X        Dispshiploc(ship),
  1378. X    Race->Playernum, ship->alive ? "attacked" : "DESTROYED", Ship(ship));
  1379. X    strcpy(long_msg, short_msg);
  1380. X    strcat(long_msg, damage_msg);
  1381. X
  1382. X    return damage;
  1383. X}
  1384. X#endif
  1385. X
  1386. Xint 
  1387. Xshoot_ship_to_planet(shiptype * ship, planettype * pl, int strength, int x,
  1388. X             int y, int getmap, int ignore, int caliber,
  1389. X             char *long_msg, char *short_msg)
  1390. X{
  1391. X    register sectortype *s, *target;
  1392. X    register int    x2, y2;
  1393. X    int             numdest, kills, oldowner;
  1394. X    int             i, num_sectors, sum_mob[MAXPLAYERS];
  1395. X    double          d, r, fac;
  1396. X
  1397. X    numdest = 0;
  1398. X    if (strength <= 0)
  1399. X        return -1;
  1400. X    if (!(ship->alive || ignore))
  1401. X        return -1;
  1402. X    if (has_switch(ship) && !ship->on)
  1403. X        return -1;
  1404. X    if (ship->whatorbits != LEVEL_PLAN)
  1405. X        return -1;
  1406. X
  1407. X    if (x < 0 || x > pl->Maxx - 1 || y < 0 || y > pl->Maxy - 1)
  1408. X        return -1;
  1409. X
  1410. X    r = .4 * strength;
  1411. X    if (!caliber) {        /* figure out the appropriate gun caliber if
  1412. X                 * not given */
  1413. X        if (ship->fire_laser)
  1414. X            caliber = LIGHT;
  1415. X        else
  1416. X            switch (ship->guns) {
  1417. X            case PRIMARY:
  1418. X                caliber = ship->primtype;
  1419. X                break;
  1420. X            case SECONDARY:
  1421. X                caliber = ship->sectype;
  1422. X                break;
  1423. X            default:
  1424. X                caliber = LIGHT;
  1425. X            }
  1426. X    }
  1427. X    if (getmap) {
  1428. X        getsmap(Smap, pl);
  1429. X    }
  1430. X    target = &Sector(*pl, x, y);
  1431. X    oldowner = target->owner;
  1432. X
  1433. X    for (i = 1; i <= Num_races; i++)
  1434. X        sum_mob[i - 1] = 0;
  1435. X
  1436. X    for (y2 = 0; y2 < pl->Maxy; y2++) {
  1437. X        for (x2 = 0; x2 < pl->Maxx; x2++) {
  1438. X            register int    dx, dy;
  1439. X            dx = MIN(abs(x2 - x), abs(x + (pl->Maxx - 1) - x2));
  1440. X            dy = abs(y2 - y);
  1441. X            d = sqrt((double) (dx * dx + dy * dy));
  1442. X            s = &Sector(*pl, x2, y2);
  1443. X
  1444. X            if (d <= r) {
  1445. X                fac = SECTOR_DAMAGE * (double) strength *(double) caliber / (d + 1.);
  1446. X
  1447. X                if (s->owner) {
  1448. X                    if (s->popn) {
  1449. X                        kills = int_rand(0, ((int) (fac / 10.0) * s->popn))
  1450. X                            / (1 + (s->condition == PLATED));
  1451. X                        if (kills > s->popn)
  1452. X                            s->popn = 0;
  1453. X                        else
  1454. X                            s->popn -= kills;
  1455. X                    }
  1456. X                    if (s->troops &&
  1457. X                        (fac > 5.0 * (double) Defensedata[s->condition])) {
  1458. X                        kills = int_rand(0, ((int) (fac / 20.0) * s->troops))
  1459. X                            / (1 + (s->condition == PLATED));
  1460. X                        if (kills > s->troops)
  1461. X                            s->troops = 0;
  1462. X                        else
  1463. X                            s->troops -= kills;
  1464. X                    }
  1465. X                    if (!(s->popn + s->troops))
  1466. X                        s->owner = 0;
  1467. X                }
  1468. X                if (fac >= 5.0 && !int_rand(0, 10))
  1469. X                    mutate_sector(s);
  1470. X
  1471. X                if (round_rand(fac) >
  1472. X                    Defensedata[s->condition] * int_rand(0, 10)) {
  1473. X                    if (s->owner)
  1474. X                        Nuked[s->owner - 1] = 1;
  1475. X                    s->popn = 0;
  1476. X                    s->troops = int_rand(0, (int) s->troops);
  1477. X                    if (!s->troops)    /* troops may survive
  1478. X                             * this */
  1479. X                        s->owner = 0;
  1480. X                    s->eff = 0;
  1481. X                    s->resource = s->resource / ((int) fac + 1);
  1482. X                    s->mobilization = 0;
  1483. X                    s->fert = 0;    /* all is lost ! */
  1484. X                    s->crystals = int_rand(0, (int) s->crystals);
  1485. X                    s->condition = WASTED;
  1486. X                    numdest++;
  1487. X                } else {
  1488. X                    s->fert = MAX(0, (int) s->fert - (int) fac);
  1489. X                    s->eff = MAX(0, (int) s->eff - (int) fac);
  1490. X                    s->mobilization = MAX(0, (int) s->mobilization - (int) fac);
  1491. X                    s->resource = MAX(0, (int) s->resource - (int) fac);
  1492. X                }
  1493. X            }
  1494. X            if (s->owner)
  1495. X                sum_mob[s->owner - 1] += s->mobilization;
  1496. X        }
  1497. X    }
  1498. X    num_sectors = pl->Maxx * pl->Maxy;
  1499. X    for (i = 1; i <= Num_races; i++) {
  1500. X        pl->info[i - 1].mob_points = sum_mob[i - 1];
  1501. X        pl->info[i - 1].comread = sum_mob[i - 1] / num_sectors;
  1502. X        pl->info[i - 1].guns = planet_guns(sum_mob[i - 1]);
  1503. X    }
  1504. X
  1505. X    /* planet toxicity goes up a bit */
  1506. X    pl->conditions[TOXIC] += (100 - pl->conditions[TOXIC]) *
  1507. X        ((double) numdest / (double) (pl->Maxx * pl->Maxy));
  1508. X
  1509. X    sprintf(short_msg, "%s bombards %s [%d]\n", Ship(ship), Dispshiploc(ship),
  1510. X        oldowner);
  1511. X    strcpy(long_msg, short_msg);
  1512. X    sprintf(buf, "\t%d sectors destroyed\n", numdest);
  1513. X    strcat(long_msg, buf);
  1514. X    if (getmap) {
  1515. X        putsmap(Smap, pl);
  1516. X    }
  1517. X    return numdest;
  1518. X}
  1519. X
  1520. Xint 
  1521. Xdo_radiation(shiptype * ship, double tech, int strength, int hits,
  1522. X         char *weapon, char *msg)
  1523. X{
  1524. X    double          fac, r;
  1525. X    int             i, arm, body, penetrate, casualties, casualties1;
  1526. X    int             dosage;
  1527. X
  1528. X    fac = (2. / 3.14159265) * atan((double) (5 * (tech + 1.0) / (ship->tech + 1.0)));
  1529. X
  1530. X    arm = MAX(0, Armor(ship) - hits / 5);
  1531. X    body = Body(ship);
  1532. X
  1533. X    penetrate = 0;
  1534. X    r = 1.0;
  1535. X    for (i = 1; i <= arm; i++)
  1536. X        r *= fac;
  1537. X
  1538. X    for (i = 1; i <= hits; i++)    /* check to see how many hits
  1539. X                     * penetrate */
  1540. X        if (double_rand() <= r)
  1541. X            penetrate += 1;
  1542. X
  1543. X    dosage = round_rand(40. * (double) penetrate / (double) body);
  1544. X    dosage = MIN(100, dosage);
  1545. X
  1546. X    if (dosage > ship->rad)
  1547. X        ship->rad = MAX(ship->rad, dosage);
  1548. X    if (success(ship->rad))
  1549. X        ship->active = 0;
  1550. X
  1551. X    casualties = 0;
  1552. X    casualties1 = 0;
  1553. X    sprintf(buf, "\tAttack: %d %s\n\t  Hits: %d\n",
  1554. X        strength, weapon, hits);
  1555. X    strcat(msg, buf);
  1556. X    sprintf(buf, "\t   Rad: %d%% for a total of %d%%\n",
  1557. X        dosage, ship->rad);
  1558. X    strcat(msg, buf);
  1559. X    if (casualties || casualties1) {
  1560. X        sprintf(buf, "\tKilled: %d civ + %d mil\n",
  1561. X            casualties, casualties1);
  1562. X        strcat(msg, buf);
  1563. X    }
  1564. X    return dosage;
  1565. X}
  1566. X
  1567. Xint 
  1568. Xdo_damage(int who, shiptype * ship, double tech, int strength, int hits,
  1569. X      int defense, int caliber, double range, char *weapon, char *msg)
  1570. X{
  1571. X    double          body;
  1572. X    int             i, arm;
  1573. X    int             damage;
  1574. X    int             penetrate, crithits, critdam;
  1575. X    int             casualties, casualties1, primgundamage, secgundamage;
  1576. X    double          fac, r;
  1577. X    char            critmsg[1024];
  1578. X
  1579. X    sprintf(buf, "\tAttack: %d %s at a range of %.0f\n",
  1580. X        strength, weapon, range);
  1581. X    strcpy(msg, buf);
  1582. X    sprintf(buf, "\t  Hits: %d  %d%% probability\n", hits, hit_probability);
  1583. X    strcat(msg, buf);
  1584. X    /* ship may lose some armor */
  1585. X    if (ship->armor)
  1586. X        if (success(hits * caliber)) {
  1587. X            ship->armor--;
  1588. X            sprintf(buf, "\t\tArmor reduced to %d\n", ship->armor);
  1589. X            strcat(msg, buf);
  1590. X        }
  1591. X    fac = p_factor(tech, ship->tech);
  1592. X    penetration_factor = fac;
  1593. X    arm = MAX(0, Armor(ship) + defense - hits / 5);
  1594. X    body = sqrt((double) (0.1 * Body(ship)));
  1595. X
  1596. X    critdam = 0;
  1597. X    crithits = 0;
  1598. X    penetrate = 0;
  1599. X    r = 1.0;
  1600. X    for (i = 1; i <= arm; i++)
  1601. X        r *= fac;
  1602. X
  1603. X    for (i = 1; i <= hits; i++)    /* check to see how many hits
  1604. X                     * penetrate */
  1605. X        if (double_rand() <= r)
  1606. X            penetrate += 1;
  1607. X
  1608. X    damage = round_rand(SHIP_DAMAGE * (double) caliber * (double) penetrate / (double) body);
  1609. X
  1610. X    do_critical_hits(penetrate, ship, &crithits, &critdam, caliber, critmsg);
  1611. X
  1612. X    if (crithits)
  1613. X        damage += critdam;
  1614. X
  1615. X    damage = MIN(100, damage);
  1616. X    ship->damage = MIN(100, (int) (ship->damage) + damage);
  1617. X    do_collateral(ship, damage, &casualties, &casualties1,
  1618. X              &primgundamage, &secgundamage);
  1619. X    /* set laser strength for ships to maximum safe limit */
  1620. X    if (ship->fire_laser) {
  1621. X        int             safe;
  1622. X        safe = (int) ((1.0 - .01 * ship->damage) * ship->tech / 4.0);
  1623. X        if (ship->fire_laser > safe)
  1624. X            ship->fire_laser = safe;
  1625. X    }
  1626. X    if (penetrate) {
  1627. X        sprintf(buf, "\t\t%d penetrations  eff armor=%d defense=%d prob=%.3f\n",
  1628. X            penetrate, arm, defense, r);
  1629. X        strcat(msg, buf);
  1630. X    }
  1631. X    if (crithits) {
  1632. X        sprintf(buf, "\t\t%d CRITICAL hits do %d%% damage\n",
  1633. X            crithits, critdam);
  1634. X        strcat(msg, buf);
  1635. X        strcat(msg, critmsg);
  1636. X    }
  1637. X    if (damage) {
  1638. X        sprintf(buf, "\tDamage: %d%% damage for a total of %d%%\n",
  1639. X            damage, ship->damage);
  1640. X        strcat(msg, buf);
  1641. X    }
  1642. X    if (primgundamage || secgundamage) {
  1643. X        sprintf(buf, "\t Other: %d primary/%d secondary guns destroyed\n",
  1644. X            primgundamage, secgundamage);
  1645. X        strcat(msg, buf);
  1646. X    }
  1647. X    if (casualties || casualties1) {
  1648. X        sprintf(buf, "\tKilled: %d civ + %d mil casualties\n",
  1649. X            casualties, casualties1);
  1650. X        strcat(msg, buf);
  1651. X    }
  1652. X    if (ship->damage >= 100)
  1653. X        kill_ship(who, ship);
  1654. X    ship->build_cost = (int) cost(ship);
  1655. X    return damage;
  1656. X}
  1657. X
  1658. Xvoid 
  1659. Xship_disposition(shiptype * ship, int *evade, int *speed, int *body)
  1660. X{
  1661. X    *evade = 0;
  1662. X    *speed = 0;
  1663. X    *body = Size(ship);
  1664. X    if (ship->active && !ship->docked &&
  1665. X        (ship->whatdest || ship->navigate.on)) {
  1666. X        *evade = ship->protect.evade;
  1667. X        *speed = ship->speed;
  1668. X    }
  1669. X    return;
  1670. X}
  1671. X
  1672. Xint 
  1673. XCEW_hit(double dist, int cew_range)
  1674. X{
  1675. X    int             prob, hits;
  1676. X
  1677. X    hits = 0;
  1678. X    prob = cew_hit_odds(dist, cew_range);
  1679. X
  1680. X    if (success(prob))
  1681. X        hits = 1;
  1682. X
  1683. X    return hits;
  1684. X}
  1685. X
  1686. Xint 
  1687. XNum_hits(double dist, int focus, int guns, double tech, int fdam,
  1688. X     int fev, int tev, int fspeed, int tspeed, int body,
  1689. X     int caliber, int defense)
  1690. X{
  1691. X    int             factor;
  1692. X    int             i, prob, hits;
  1693. X
  1694. X    prob = hit_odds(dist, &factor, tech, fdam,
  1695. X            fev, tev, fspeed, tspeed, body, caliber, defense);
  1696. X
  1697. X    hits = 0;
  1698. X    if (focus) {
  1699. X        if (success(prob * prob / 100))
  1700. X            hits = guns;
  1701. X        hit_probability = prob * prob / 100;
  1702. X    } else {
  1703. X        for (i = 1; i <= guns; i++)
  1704. X            if (success(prob))
  1705. X                hits++;
  1706. X        hit_probability = prob;    /* global variable */
  1707. X    }
  1708. X
  1709. X    return hits;
  1710. X}
  1711. X
  1712. Xint 
  1713. Xhit_odds(double range, int *factor, double tech, int fdam, int fev,
  1714. X     int tev, int fspeed, int tspeed, int body, int caliber, int defense)
  1715. X{
  1716. X    int             odds;
  1717. X    double          a, b, c;
  1718. X
  1719. X    if (caliber == NONE) {
  1720. X        *factor = 0;
  1721. X        return 0;
  1722. X    }
  1723. X    a = log10(1.0 + (double) tech) * 80.0 * pow((double) body, 0.33333);
  1724. X    b = 72.0 / ((2.0 + (double) tev) * (2.0 + (double) fev)
  1725. X            * (18.0 + (double) tspeed + (double) fspeed));
  1726. X    c = a * b / (double) caliber;
  1727. X    *factor = (int) (c * (1.0 - (double) fdam / 100.));    /* 50% hit range */
  1728. X    odds = 0;
  1729. X    if (*factor > 0)
  1730. X        odds = (int) ((double) ((*factor) * 100) / ((double) ((*factor) + (int) range)));
  1731. X    odds = (int) ((double) odds * (1.0 - 0.1 * (double) defense));
  1732. X    return odds;
  1733. X}
  1734. X
  1735. Xint 
  1736. Xcew_hit_odds(double range, int cew_range)
  1737. X{
  1738. X    int             odds;
  1739. X    double          factor;
  1740. X
  1741. X    factor = (range + 1.0) / ((double) cew_range + 1.0);    /* maximum chance */
  1742. X    odds = (int) (100.0 * exp((double) (-50.0 * (factor - 1.0) * (factor - 1.0))));
  1743. X    return odds;
  1744. X}
  1745. X
  1746. X/*
  1747. X * gun range of given ship, given race and ship
  1748. X */
  1749. Xdouble 
  1750. Xgun_range(racetype * r, shiptype * s, int mode)
  1751. X{
  1752. X    if (mode)
  1753. X        return (logscale((int) (r->tech + 1.0)) * SYSTEMSIZE);
  1754. X    else
  1755. X        return (logscale((int) (s->tech + 1.0)) * SYSTEMSIZE);
  1756. X}
  1757. X
  1758. X/*
  1759. X * range of telescopes, ground or space, given race and ship
  1760. X */
  1761. Xdouble 
  1762. Xtele_range(int type, double tech)
  1763. X{
  1764. X    if (type == OTYPE_GTELE)
  1765. X        return log1p((double) tech) * 400 + SYSTEMSIZE / 8;
  1766. X    else
  1767. X        return log1p((double) tech) * 1500 + SYSTEMSIZE / 3;
  1768. X}
  1769. X
  1770. Xint 
  1771. Xcurrent_caliber(shiptype * ship)
  1772. X{
  1773. X    if (ship->laser && ship->fire_laser)
  1774. X        return LIGHT;
  1775. X    else if (ship->type == STYPE_MINE)
  1776. X        return LIGHT;
  1777. X    else if (ship->type == STYPE_MISSILE)
  1778. X        return HEAVY;
  1779. X    else if (ship->guns == PRIMARY)
  1780. X        return ship->primtype;
  1781. X    else if (ship->guns == SECONDARY)
  1782. X        return ship->sectype;
  1783. X    else
  1784. X        return NONE;
  1785. X}
  1786. X
  1787. Xvoid 
  1788. Xdo_critical_hits(int penetrate, shiptype * ship, int *crithits,
  1789. X         int *critdam, int caliber, char *critmsg)
  1790. X{
  1791. X    int             eff_size, i, dam;
  1792. X    *critdam = 0;
  1793. X    *crithits = 0;
  1794. X    if (caliber < 1) caliber = 1;
  1795. X    eff_size = MAX(1, Body(ship) / caliber);
  1796. X    for (i = 1; i <= penetrate; i++)
  1797. X        if (!int_rand(0, eff_size - 1)) {
  1798. X            *crithits += 1;
  1799. X            dam = int_rand(0, 100);
  1800. X            *critdam += dam;
  1801. X        }
  1802. X    *critdam = MIN(100, *critdam);
  1803. X    /* check for special systems damage */
  1804. X    strcpy(critmsg, "\t\tSpecial systems damage: ");
  1805. X    if (ship->cew && success(*critdam)) {
  1806. X        strcat(critmsg, "CEW ");
  1807. X        ship->cew = 0;
  1808. X    }
  1809. X    if (ship->laser && success(*critdam)) {
  1810. X        strcat(critmsg, "Laser ");
  1811. X        ship->laser = 0;
  1812. X    }
  1813. X    if (ship->cloak && success(*critdam)) {
  1814. X        strcat(critmsg, "Cloak ");
  1815. X        ship->cloak = 0;
  1816. X    }
  1817. X    if (ship->hyper_drive.has && success(*critdam)) {
  1818. X        strcat(critmsg, "Hyper-drive ");
  1819. X        ship->hyper_drive.has = 0;
  1820. X    }
  1821. X    if (ship->max_speed && success(*critdam)) {
  1822. X        ship->speed = 0;
  1823. X        ship->max_speed = int_rand(0, (int) ship->max_speed - 1);
  1824. X        sprintf(buf, "Speed=%d ", ship->max_speed);
  1825. X        strcat(critmsg, buf);
  1826. X    }
  1827. X    if (ship->armor && success(*critdam)) {
  1828. X        ship->armor = int_rand(0, (int) ship->armor - 1);
  1829. X        sprintf(buf, "Armor=%d ", ship->armor);
  1830. X        strcat(critmsg, buf);
  1831. X    }
  1832. X    strcat(critmsg, "\n");
  1833. X}
  1834. X
  1835. Xvoid 
  1836. Xdo_collateral(shiptype * ship, int damage, int *casualties,
  1837. X          int *casualties1, int *primgundamage, int *secgundamage)
  1838. X{
  1839. X    int             i;
  1840. X    /* compute crew/troop casualties */
  1841. X    *casualties = 0;
  1842. X    *casualties1 = 0;
  1843. X    *primgundamage = 0;
  1844. X    *secgundamage = 0;
  1845. X
  1846. X    for (i = 1; i <= ship->popn; i++)
  1847. X        *casualties += success(damage);
  1848. X    ship->popn -= *casualties;
  1849. X    for (i = 1; i <= ship->troops; i++)
  1850. X        *casualties1 += success(damage);
  1851. X    ship->troops -= *casualties1;
  1852. X    for (i = 1; i <= ship->primary; i++)
  1853. X        *primgundamage += success(damage);
  1854. X    ship->primary -= *primgundamage;
  1855. X    for (i = 1; i <= ship->secondary; i++)
  1856. X        *secgundamage += success(damage);
  1857. X    ship->secondary -= *secgundamage;
  1858. X    if (!ship->primary)
  1859. X        ship->primtype = NONE;
  1860. X    if (!ship->secondary)
  1861. X        ship->sectype = NONE;
  1862. X}
  1863. X
  1864. Xint 
  1865. Xgetdefense(shiptype * ship)
  1866. X{
  1867. X    planettype     *p;
  1868. X    sectortype     *sect;
  1869. X    int             defense = 0;
  1870. X
  1871. X    if (landed(ship)) {
  1872. X        getplanet(&p, (int) ship->storbits, (int) ship->pnumorbits);
  1873. X        getsector(§, p, (int) ship->land_x, (int) ship->land_y);
  1874. X        defense = 2 * Defensedata[sect->condition];
  1875. X        free(p);
  1876. X        free(sect);
  1877. X    }
  1878. X    return defense;
  1879. X}
  1880. X
  1881. Xdouble 
  1882. Xp_factor(double attacker, double defender)
  1883. X{
  1884. X    return ((2. / 3.141592) * atan(5 * (double) ((attacker + 1.0) / (defender + 1.0))));
  1885. X}
  1886. X
  1887. Xint 
  1888. Xplanet_guns(int points)
  1889. X{
  1890. X    if (points < 0)
  1891. X        return 0;    /* shouldn't happen */
  1892. X    return MIN(20, points / 1000);
  1893. X}
  1894. X
  1895. Xvoid 
  1896. Xmutate_sector(sectortype * s)
  1897. X{
  1898. X    if (int_rand(0, 6) >= Defensedata[s->condition])
  1899. X        s->condition = s->type;
  1900. X}
  1901. END_OF_FILE
  1902. if test 18678 -ne `wc -c <'user/shootblast.c'`; then
  1903.     echo shar: \"'user/shootblast.c'\" unpacked with wrong size!
  1904. fi
  1905. # end of 'user/shootblast.c'
  1906. fi
  1907. echo shar: End of archive 8 \(of 21\).
  1908. cp /dev/null ark8isdone
  1909. MISSING=""
  1910. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
  1911.     if test ! -f ark${I}isdone ; then
  1912.     MISSING="${MISSING} ${I}"
  1913.     fi
  1914. done
  1915. if test "${MISSING}" = "" ; then
  1916.     echo You have unpacked all 21 archives.
  1917.     echo "Now type './buildfiles.sh'"
  1918.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1919. else
  1920.     echo You still need to unpack the following archives:
  1921.     echo "        " ${MISSING}
  1922. fi
  1923. ##  End of shell archive.
  1924. exit 0
  1925.