home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume17 / gbp / part02 < prev    next >
Encoding:
Internet Message Format  |  1993-03-20  |  55.8 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: v17i014:  gbp - Galactic Bloodshed+, an empire-like war game, Part02/21
  5. Message-ID: <4542@master.CNA.TEK.COM>
  6. Date: 12 Feb 93 17:29:51 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 1832
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1693
  11.  
  12. Submitted-by: deragon@harpo.cs.nyu.edu (Seeker)
  13. Posting-number: Volume 17, Issue 14
  14. Archive-name: gbp/Part02
  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 2 (of 21)."
  27. # Contents:  server/perm.c user/build.c2
  28. # Wrapped by billr@saab on Fri Feb 12 09:14:23 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'server/perm.c' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'server/perm.c'\"
  32. else
  33. echo shar: Extracting \"'server/perm.c'\" \(1355 characters\)
  34. sed "s/^X//" >'server/perm.c' <<'END_OF_FILE'
  35. X/*
  36. X * Galactic Bloodshed, copyright (c) 1989 by Robert P. Chansky,
  37. X * smq@ucscb.ucsc.edu, mods by people in GB_copyright.h. Restrictions in
  38. X * GB_copyright.h.
  39. X * 
  40. X * perm.c -- randomly permute a sector list
  41. X */
  42. X
  43. X#include "GB_copyright.h"
  44. X#define EXTERN extern
  45. X#include "vars.h"
  46. X
  47. X#include "races.h"
  48. X#include "ships.h"
  49. X#include "power.h"
  50. X#include "proto.h"
  51. X
  52. Xstruct map {
  53. X    char            x, y;
  54. X}               xymap[(MAX_X + 1) * (MAX_Y + 1)];
  55. X
  56. Xvoid            PermuteSects(planettype *);
  57. Xint             Getxysect(planettype *, int *, int *, int);
  58. X
  59. X/* make a random list of sectors. */
  60. Xvoid 
  61. XPermuteSects(planettype * planet)
  62. X{
  63. X    register int    i, j, x, y, t;
  64. X    struct map      sw;
  65. X
  66. X    t = planet->Maxy * planet->Maxx;
  67. X
  68. X    for (i = x = y = 0; i < t; i++) {
  69. X        xymap[i].x = x;
  70. X        xymap[i].y = y;
  71. X        if (++x >= planet->Maxx)
  72. X            x = 0, y++;
  73. X    }
  74. X    for (i = 0; i < t; i++) {
  75. X        sw = xymap[i];
  76. X        xymap[i] = xymap[j = int_rand(0, t - 1)];
  77. X        xymap[j] = sw;
  78. X    }
  79. X}
  80. X
  81. X/*
  82. X * get the next x,y sector in the list.  if r=1, reset the counter. *
  83. X * increments the counter & returns whether or not this reset it to 0.
  84. X */
  85. X
  86. Xint 
  87. XGetxysect(reg planettype * p, reg int *x, reg int *y, reg int r)
  88. X{
  89. X    static int      getxy, max;
  90. X
  91. X    if (r) {
  92. X        getxy = 0;
  93. X        max = p->Maxx * p->Maxy;
  94. X    } else {
  95. X        *x = xymap[getxy].x;
  96. X        *y = xymap[getxy].y;
  97. X        if (++getxy > max)
  98. X            getxy = 0;
  99. X    }
  100. X    return getxy;
  101. X}
  102. END_OF_FILE
  103. if test 1355 -ne `wc -c <'server/perm.c'`; then
  104.     echo shar: \"'server/perm.c'\" unpacked with wrong size!
  105. fi
  106. # end of 'server/perm.c'
  107. fi
  108. if test -f 'user/build.c2' -a "${1}" != "-c" ; then 
  109.   echo shar: Will not clobber existing file \"'user/build.c2'\"
  110. else
  111. echo shar: Extracting \"'user/build.c2'\" \(51681 characters\)
  112. sed "s/^X//" >'user/build.c2' <<'END_OF_FILE'
  113. Xvoid 
  114. Xmake_mod(int Playernum, int Governor, int APcount, int mode)
  115. X{
  116. X    int             i, value;
  117. X    unsigned short  size;
  118. X    char            shipc;
  119. X    shiptype       *dirship;
  120. X    racetype       *Race;
  121. X    double          cost0;
  122. X
  123. X    if (Dir[Playernum - 1][Governor].level != LEVEL_SHIP) {
  124. X        notify(Playernum, Governor, "You have to change scope to an installation.\n");
  125. X        return;
  126. X    }
  127. X    if (!getship(&dirship, Dir[Playernum - 1][Governor].shipno)) {
  128. X        sprintf(buf, "Illegal dir value.\n");
  129. X        notify(Playernum, Governor, buf);
  130. X        return;
  131. X    }
  132. X    if (testship(Playernum, Governor, dirship)) {
  133. X        free(dirship);
  134. X        return;
  135. X    }
  136. X    if (dirship->type != OTYPE_FACTORY) {
  137. X        notify(Playernum, Governor, "That is not a factory.\n");
  138. X        free(dirship);
  139. X        return;
  140. X    }
  141. X    if (dirship->on && argn > 1) {
  142. X        notify(Playernum, Governor, "This factory is already online.\n");
  143. X        free(dirship);
  144. X        return;
  145. X    }
  146. X    Race = races[Playernum - 1];
  147. X
  148. X    /*
  149. X     * Save  size of the factory, and set it to the correct values for
  150. X     * the design.  Maarten
  151. X     */
  152. X    size = dirship->size;
  153. X    dirship->size = ship_size(dirship);
  154. X
  155. X    if (mode == 0) {
  156. X        if (argn < 2) {    /* list the current settings for the factory */
  157. X            if (!dirship->build_type) {
  158. X                notify(Playernum, Governor, "No ship type specified.\n");
  159. X                free(dirship);
  160. X                return;
  161. X            }
  162. X            notify(Playernum, Governor, "  --- Current Production Specifications ---\n");
  163. X            sprintf(buf, "%s\t\t\tArmor:    %4d\t\tGuns:",
  164. X                (dirship->on ? "Online" : "Offline"), dirship->armor);
  165. X            notify(Playernum, Governor, buf);
  166. X            if (Shipdata[dirship->build_type][ABIL_PRIMARY] &&
  167. X                dirship->primtype != NONE) {
  168. X                sprintf(buf, "%3d%c", dirship->primary,
  169. X                    (dirship->primtype == LIGHT ? 'L' :
  170. X                     dirship->primtype == MEDIUM ? 'M' :
  171. X                   dirship->primtype == HEAVY ? 'H' : 'N'));
  172. X                notify(Playernum, Governor, buf);
  173. X            }
  174. X            if (Shipdata[dirship->build_type][ABIL_SECONDARY] &&
  175. X                dirship->sectype != NONE) {
  176. X                sprintf(buf, "/%d%c", dirship->secondary,
  177. X                    (dirship->sectype == LIGHT ? 'L' :
  178. X                     dirship->sectype == MEDIUM ? 'M' :
  179. X                    dirship->sectype == HEAVY ? 'H' : 'N'));
  180. X                notify(Playernum, Governor, buf);
  181. X            }
  182. X            notify(Playernum, Governor, "\n");
  183. X            sprintf(buf, "Ship:  %-16.16s\tCrew:     %4d",
  184. X             Shipnames[dirship->build_type], dirship->max_crew);
  185. X            notify(Playernum, Governor, buf);
  186. X            if (Shipdata[dirship->build_type][ABIL_MOUNT]) {
  187. X                sprintf(buf, "\t\tXtal Mount: %s\n",
  188. X                    (dirship->mount ? "yes" : "no"));
  189. X                notify(Playernum, Governor, buf);
  190. X            } else
  191. X                notify(Playernum, Governor, "\n");
  192. X            sprintf(buf, "Class: %s\t\tFuel:     %4d",
  193. X                dirship->class, dirship->max_fuel);
  194. X            notify(Playernum, Governor, buf);
  195. X            if (Shipdata[dirship->build_type][ABIL_JUMP]) {
  196. X                sprintf(buf, "\t\tHyperdrive: %s\n",
  197. X                 (dirship->hyper_drive.has ? "yes" : "no"));
  198. X                notify(Playernum, Governor, buf);
  199. X            } else
  200. X                notify(Playernum, Governor, "\n");
  201. X            sprintf(buf, "Cost:  %d r\t\tCargo:    %4d",
  202. X                dirship->build_cost, dirship->max_resource);
  203. X            notify(Playernum, Governor, buf);
  204. X            if (Shipdata[dirship->build_type][ABIL_LASER]) {
  205. X                sprintf(buf, "\t\tCombat Lasers: %s\n",
  206. X                    (dirship->laser ? "yes" : "no"));
  207. X                notify(Playernum, Governor, buf);
  208. X            } else
  209. X                notify(Playernum, Governor, "\n");
  210. X            sprintf(buf, "Mass:  %.1f\t\tHanger:   %4u",
  211. X                dirship->base_mass, dirship->max_hanger);
  212. X            notify(Playernum, Governor, buf);
  213. X            if (Shipdata[dirship->build_type][ABIL_CEW]) {
  214. X                sprintf(buf, "\t\tCEW: %s\n",
  215. X                    (dirship->cew ? "yes" : "no"));
  216. X                notify(Playernum, Governor, buf);
  217. X            } else
  218. X                notify(Playernum, Governor, "\n");
  219. X            sprintf(buf, "Size:  %-6d\t\tDestruct: %4d",
  220. X                dirship->size, dirship->max_destruct);
  221. X            notify(Playernum, Governor, buf);
  222. X            if (Shipdata[dirship->build_type][ABIL_CEW] && dirship->cew) {
  223. X                sprintf(buf, "\t\t   Opt Range: %4d\n", dirship->cew_range);
  224. X                notify(Playernum, Governor, buf);
  225. X            } else
  226. X                notify(Playernum, Governor, "\n");
  227. X            sprintf(buf, "Tech:  %.1f (%.1f)\tSpeed:    %4d",
  228. X            dirship->complexity, Race->tech, dirship->max_speed);
  229. X            notify(Playernum, Governor, buf);
  230. X            if (Shipdata[dirship->build_type][ABIL_CEW] && dirship->cew) {
  231. X                sprintf(buf, "\t\t   Energy:    %4d\n", dirship->cew);
  232. X                notify(Playernum, Governor, buf);
  233. X            } else
  234. X                notify(Playernum, Governor, "\n");
  235. X
  236. X            if (Race->tech < dirship->complexity)
  237. X                notify(Playernum, Governor, "Your engineering capability is not advanced enough to produce this design.\n");
  238. X            free(dirship);
  239. X            return;
  240. X        }
  241. X        shipc = args[1][0];
  242. X
  243. X        i = 0;
  244. X        while ((Shipltrs[i] != shipc) && (i < NUMSTYPES))
  245. X            i++;
  246. X
  247. X        if ((i >= NUMSTYPES) || ((i == STYPE_POD) && (!Race->pods))) {
  248. X            sprintf(buf, "Illegal ship letter.\n");
  249. X            notify(Playernum, Governor, buf);
  250. X            free(dirship);
  251. X            return;
  252. X        }
  253. X        if (!(Shipdata[i][ABIL_BUILD] & Shipdata[OTYPE_FACTORY][ABIL_CONSTRUCT])) {
  254. X            notify(Playernum, Governor, "This kind of ship does not require a factory to construct.\n");
  255. X            free(dirship);
  256. X            return;
  257. X        }
  258. X        dirship->build_type = i;
  259. X        dirship->armor = Shipdata[i][ABIL_ARMOR];
  260. X        dirship->guns = NONE;    /* this keeps track of the factory
  261. X                     * status! */
  262. X        dirship->primary = Shipdata[i][ABIL_GUNS];
  263. X        dirship->primtype = Shipdata[i][ABIL_PRIMARY];
  264. X        dirship->secondary = Shipdata[i][ABIL_GUNS];
  265. X        dirship->sectype = Shipdata[i][ABIL_SECONDARY];
  266. X        dirship->max_crew = Shipdata[i][ABIL_MAXCREW];
  267. X        dirship->max_resource = Shipdata[i][ABIL_CARGO];
  268. X        dirship->max_hanger = Shipdata[i][ABIL_HANGER];
  269. X        dirship->max_fuel = Shipdata[i][ABIL_FUELCAP];
  270. X        dirship->max_destruct = Shipdata[i][ABIL_DESTCAP];
  271. X        dirship->max_speed = Shipdata[i][ABIL_SPEED];
  272. X
  273. X        dirship->mount = Shipdata[i][ABIL_MOUNT] * Crystal(Race);
  274. X        dirship->hyper_drive.has = Shipdata[i][ABIL_JUMP] * Hyper_drive(Race);
  275. X        dirship->cloak = Shipdata[i][ABIL_CLOAK] * Cloak(Race);
  276. X        dirship->laser = Shipdata[i][ABIL_LASER] * Laser(Race);
  277. X        dirship->cew = 0;
  278. X        dirship->mode = 0;
  279. X
  280. X        dirship->size = ship_size(dirship);
  281. X        dirship->complexity = complexity(dirship);
  282. X
  283. X        sprintf(dirship->class, "mod %d", Dir[Playernum - 1][Governor].shipno);
  284. X
  285. X        sprintf(buf, "Factory designated to produce %ss.\n", Shipnames[i]);
  286. X        notify(Playernum, Governor, buf);
  287. X        sprintf(buf, "Design complexity %.1f (%.1f).\n", dirship->complexity,
  288. X            Race->tech);
  289. X        notify(Playernum, Governor, buf);
  290. X        if (dirship->complexity > Race->tech)
  291. X            notify(Playernum, Governor, "You can't produce this design yet!\n");
  292. X
  293. X    } else if (mode == 1) {
  294. X
  295. X        if (!dirship->build_type) {
  296. X            notify(Playernum, Governor, "No ship design specified. Use 'make <ship type>' first.\n");
  297. X            free(dirship);
  298. X            return;
  299. X        }
  300. X        if (argn < 2) {
  301. X            notify(Playernum, Governor, "You have to specify the characteristic you wish to modify.\n");
  302. X            free(dirship);
  303. X            return;
  304. X        }
  305. X        if (argn == 3)
  306. X            sscanf(args[2], "%d", &value);
  307. X        else
  308. X            value = 0;
  309. X
  310. X        if (value < 0) {
  311. X            notify(Playernum, Governor, "That's a ridiculous setting.\n");
  312. X            free(dirship);
  313. X            return;
  314. X        }
  315. X        if (Shipdata[dirship->build_type][ABIL_MOD]) {
  316. X
  317. X            if (match(args[1], "armor")) {
  318. X                dirship->armor = MIN(value, 100);
  319. X            } else if (match(args[1], "crew")
  320. X               && Shipdata[dirship->build_type][ABIL_MAXCREW]) {
  321. X                dirship->max_crew = MIN(value, 10000);
  322. X            } else if (match(args[1], "cargo")
  323. X                 && Shipdata[dirship->build_type][ABIL_CARGO]) {
  324. X                dirship->max_resource = MIN(value, 10000);
  325. X            } else if (match(args[1], "hanger")
  326. X                && Shipdata[dirship->build_type][ABIL_HANGER]) {
  327. X                dirship->max_hanger = MIN(value, 10000);
  328. X            } else if (match(args[1], "fuel")
  329. X               && Shipdata[dirship->build_type][ABIL_FUELCAP]) {
  330. X                dirship->max_fuel = MIN(value, 10000);
  331. X            } else if (match(args[1], "destruct")
  332. X               && Shipdata[dirship->build_type][ABIL_DESTCAP]) {
  333. X                dirship->max_destruct = MIN(value, 10000);
  334. X            } else if (match(args[1], "speed")
  335. X                 && Shipdata[dirship->build_type][ABIL_SPEED]) {
  336. X                dirship->max_speed = MAX(1, MIN(value, 9));
  337. X            } else if (match(args[1], "mount")
  338. X                && Shipdata[dirship->build_type][ABIL_MOUNT]
  339. X                   && Crystal(Race)) {
  340. X                dirship->mount = !dirship->mount;
  341. X            } else if (match(args[1], "hyperdrive")
  342. X                 && Shipdata[dirship->build_type][ABIL_JUMP]
  343. X                   && Hyper_drive(Race)) {
  344. X                dirship->hyper_drive.has = !dirship->hyper_drive.has;
  345. X            } else if (match(args[1], "primary")
  346. X               && Shipdata[dirship->build_type][ABIL_PRIMARY]) {
  347. X                if (match(args[2], "strength")) {
  348. X                    dirship->primary = atoi(args[3]);
  349. X                } else if (match(args[2], "caliber")) {
  350. X                    if (match(args[3], "light"))
  351. X                        dirship->primtype = LIGHT;
  352. X                    else if (match(args[3], "medium"))
  353. X                        dirship->primtype = MEDIUM;
  354. X                    else if (match(args[3], "heavy"))
  355. X                        dirship->primtype = HEAVY;
  356. X                    else {
  357. X                        notify(Playernum, Governor, "No such caliber.\n");
  358. X                        free(dirship);
  359. X                        return;
  360. X                    }
  361. X                    dirship->primtype = MIN(Shipdata[dirship->build_type][ABIL_PRIMARY],
  362. X                             dirship->primtype);
  363. X                } else {
  364. X                    notify(Playernum, Governor, "No such gun characteristic.\n");
  365. X                    free(dirship);
  366. X                    return;
  367. X                }
  368. X            } else if (match(args[1], "secondary")
  369. X             && Shipdata[dirship->build_type][ABIL_SECONDARY]) {
  370. X                if (match(args[2], "strength")) {
  371. X                    dirship->secondary = atoi(args[3]);
  372. X                } else if (match(args[2], "caliber")) {
  373. X                    if (match(args[3], "light"))
  374. X                        dirship->sectype = LIGHT;
  375. X                    else if (match(args[3], "medium"))
  376. X                        dirship->sectype = MEDIUM;
  377. X                    else if (match(args[3], "heavy"))
  378. X                        dirship->sectype = HEAVY;
  379. X                    else {
  380. X                        notify(Playernum, Governor, "No such caliber.\n");
  381. X                        free(dirship);
  382. X                        return;
  383. X                    }
  384. X                    dirship->sectype = MIN(Shipdata[dirship->build_type][ABIL_SECONDARY],
  385. X                              dirship->sectype);
  386. X                } else {
  387. X                    notify(Playernum, Governor, "No such gun characteristic.\n");
  388. X                    free(dirship);
  389. X                    return;
  390. X                }
  391. X            } else if (match(args[1], "cew")
  392. X                   && Shipdata[dirship->build_type][ABIL_CEW]) {
  393. X                if (!Cew(Race)) {
  394. X                    sprintf(buf, "Your race does not understand confined energy weapons.\n");
  395. X                    notify(Playernum, Governor, buf);
  396. X                    free(dirship);
  397. X                    return;
  398. X                }
  399. X                if (!Shipdata[dirship->build_type][ABIL_CEW]) {
  400. X                    notify(Playernum, Governor, "This kind of ship cannot mount confined energy weapons.\n");
  401. X                    free(dirship);
  402. X                    return;
  403. X                }
  404. X                value = atoi(args[3]);
  405. X                if (match(args[2], "strength")) {
  406. X                    dirship->cew = value;
  407. X                } else if (match(args[2], "range")) {
  408. X                    dirship->cew_range = value;
  409. X                } else {
  410. X                    notify(Playernum, Governor, "No such option for CEWs.\n");
  411. X                    free(dirship);
  412. X                    return;
  413. X                }
  414. X            } else if (match(args[1], "laser")
  415. X                 && Shipdata[dirship->build_type][ABIL_LASER]) {
  416. X                if (!Laser(Race)) {
  417. X                    sprintf(buf, "Your race does not understand lasers yet.\n");
  418. X                    notify(Playernum, Governor, buf);
  419. X                    free(dirship);
  420. X                    return;
  421. X                }
  422. X                if (Shipdata[dirship->build_type][ABIL_LASER])
  423. X                    dirship->laser = !dirship->laser;
  424. X                else {
  425. X                    notify(Playernum, Governor, "That ship cannot be fitted with combat lasers.\n");
  426. X                    free(dirship);
  427. X                    return;
  428. X                }
  429. X            } else {
  430. X                notify(Playernum, Governor, "That characteristic either doesn't exist or can't be modified.\n");
  431. X                free(dirship);
  432. X                return;
  433. X            }
  434. X        } else if (Hyper_drive(Race)) {
  435. X            if (match(args[1], "hyperdrive")) {
  436. X                dirship->hyper_drive.has = !dirship->hyper_drive.has;
  437. X            } else {
  438. X                notify(Playernum, Governor, "You may only modify hyperdrive installation on this kind of ship.\n");
  439. X                free(dirship);
  440. X                return;
  441. X            }
  442. X        } else {
  443. X            notify(Playernum, Governor, "Sorry, but you can't modify this ship right now.\n");
  444. X            free(dirship);
  445. X            return;
  446. X        }
  447. X    } else {
  448. X        notify(Playernum, Governor, "Weird error.\n");
  449. X        free(dirship);
  450. X        return;
  451. X    }
  452. X    /* compute how much it's going to cost to build the ship */
  453. X
  454. X    if ((cost0 = cost(dirship)) > 65535.0) {
  455. X        notify(Playernum, Governor, "Woah!! YOU CHEATER!!!  The max cost allowed is 65535!!! I'm Telllllllling!!!\n");
  456. X        free(dirship);
  457. X        return;
  458. X    }
  459. X    dirship->build_cost = Race->God ? 0 : (int) cost0;
  460. X    sprintf(buf, "The current cost of the ship is %d resources.\n",
  461. X        dirship->build_cost);
  462. X    notify(Playernum, Governor, buf);
  463. X    dirship->size = ship_size(dirship);
  464. X    dirship->base_mass = getmass(dirship);
  465. X    sprintf(buf, "The current base mass of the ship is %.1f - size is %d.\n",
  466. X        dirship->base_mass, dirship->size);
  467. X    notify(Playernum, Governor, buf);
  468. X    dirship->complexity = complexity(dirship);
  469. X    sprintf(buf, "Ship complexity is %.1f (you have %.1f engineering technology).\n", dirship->complexity, Race->tech);
  470. X    notify(Playernum, Governor, buf);
  471. X
  472. X    /* Restore size to what it was before.  Maarten */
  473. X    dirship->size = size;
  474. X
  475. X    putship(dirship);
  476. X    free(dirship);
  477. X}
  478. X
  479. Xvoid 
  480. Xbuild(int Playernum, int Governor, int APcount)
  481. X{
  482. X    racetype       *Race;
  483. X    char            c;
  484. X    int             i, j, m, n, x, y, count, level, what, outside;
  485. X    int             shipcost, load_crew;
  486. X    int             snum, pnum, build_level;
  487. X    double          load_fuel, tech;
  488. X
  489. X    FILE           *fd;
  490. X    planettype     *planet;
  491. X    sectortype     *sector;
  492. X    shiptype       *builder;
  493. X    shiptype        newship;
  494. X
  495. X    if (argn > 1 && args[1][0] == '?') {
  496. X        /* information request */
  497. X        if (argn == 2) {
  498. X            /* Ship parameter list */
  499. X            notify(Playernum, Governor, "     - Default ship parameters -\n");
  500. X            sprintf(buf, "%1s %-15s %5s %5s %3s %4s %3s %3s %3s %4s %4s %2s %4s %4s\n",
  501. X                "?", "name", "cargo", "hang", "arm", "dest", "gun", "pri",
  502. X                "sec", "fuel", "crew", "sp", "tech", "cost");
  503. X            notify(Playernum, Governor, buf);
  504. X            Race = races[Playernum - 1];
  505. X            for (j = 0; j < NUMSTYPES; j++) {
  506. X                i = ShipVector[j];
  507. X                if (Race->pods || (i != STYPE_POD)) {
  508. X                    if (Shipdata[i][ABIL_PROGRAMMED]) {
  509. X                        sprintf(buf, "%1c %-15.15s %5d %5d %3d %4d %3d %3d %3d %4d %4d %2d %4.0f %4d\n",
  510. X                          Shipltrs[i], Shipnames[i],
  511. X                            Shipdata[i][ABIL_CARGO],
  512. X                           Shipdata[i][ABIL_HANGER],
  513. X                            Shipdata[i][ABIL_ARMOR],
  514. X                          Shipdata[i][ABIL_DESTCAP],
  515. X                             Shipdata[i][ABIL_GUNS],
  516. X                          Shipdata[i][ABIL_PRIMARY],
  517. X                        Shipdata[i][ABIL_SECONDARY],
  518. X                          Shipdata[i][ABIL_FUELCAP],
  519. X                          Shipdata[i][ABIL_MAXCREW],
  520. X                            Shipdata[i][ABIL_SPEED],
  521. X                            (double) Shipdata[i][ABIL_TECH],
  522. X                            Shipcost(i, Race));
  523. X                        notify(Playernum, Governor, buf);
  524. X                    }
  525. X                }
  526. X            }
  527. X            return;
  528. X        } else {
  529. X            /* Description of specific ship type */
  530. X            i = 0;
  531. X            while (Shipltrs[i] != args[2][0] && i < NUMSTYPES)
  532. X                i++;
  533. X            if (i < 0 || i >= NUMSTYPES)
  534. X                notify(Playernum, Governor, "No such ship type.\n");
  535. X            else if (!Shipdata[i][ABIL_PROGRAMMED])
  536. X                notify(Playernum, Governor, "This ship type has not been programmed.\n");
  537. X            else {
  538. X                if ((fd = fopen(EXAM_FL, "r")) == NULL) {
  539. X                    perror(EXAM_FL);
  540. X                    return;
  541. X                } else {
  542. X                    /* look through ship description file */
  543. X                    sprintf(buf, "\n");
  544. X                    for (j = 0; j <= i; j++)
  545. X                        while (fgetc(fd) != '~');
  546. X                    /* Give description */
  547. X                    while ((c = fgetc(fd)) != '~') {
  548. X                        sprintf(temp, "%c", c);
  549. X                        strcat(buf, temp);
  550. X                    }
  551. X                    fclose(fd);
  552. X                    /* Built where? */
  553. X                    if (Shipdata[i][ABIL_BUILD] & 1) {
  554. X                        sprintf(temp, "\nCan be constructed on planet.");
  555. X                        strcat(buf, temp);
  556. X                    }
  557. X                    n = 0;
  558. X                    sprintf(temp, "\nCan be built by ");
  559. X                    for (j = 0; j < NUMSTYPES; j++)
  560. X                        if (Shipdata[i][ABIL_BUILD] & Shipdata[j][ABIL_CONSTRUCT])
  561. X                            n++;
  562. X                    if (n) {
  563. X                        m = 0;
  564. X                        strcat(buf, temp);
  565. X                        for (j = 0; j < NUMSTYPES; j++) {
  566. X                            if (Shipdata[i][ABIL_BUILD] &
  567. X                                Shipdata[j][ABIL_CONSTRUCT]) {
  568. X                                m++;
  569. X                                if (n - m > 1)
  570. X                                    sprintf(temp, "%c, ", Shipltrs[j]);
  571. X                                else if (n - m > 0)
  572. X                                    sprintf(temp, "%c and ", Shipltrs[j]);
  573. X                                else
  574. X                                    sprintf(temp, "%c ", Shipltrs[j]);
  575. X                                strcat(buf, temp);
  576. X                            }
  577. X                        }
  578. X                        sprintf(temp, "type ships.\n");
  579. X                        strcat(buf, temp);
  580. X                    }
  581. X                    /* default parameters */
  582. X                    sprintf(temp, "\n%1s %-15s %5s %5s %3s %4s %3s %3s %3s %4s %4s %2s %4s %4s\n",
  583. X                        "?", "name", "cargo", "hang", "arm", "dest", "gun",
  584. X                        "pri", "sec", "fuel", "crew", "sp", "tech", "cost");
  585. X                    strcat(buf, temp);
  586. X                    Race = races[Playernum - 1];
  587. X                    sprintf(temp, "%1c %-15.15s %5d %5d %3d %4d %3d %3d %3d %4d %4d %2d %4.0f %4d\n",
  588. X                        Shipltrs[i], Shipnames[i],
  589. X                        Shipdata[i][ABIL_CARGO],
  590. X                        Shipdata[i][ABIL_HANGER],
  591. X                        Shipdata[i][ABIL_ARMOR],
  592. X                        Shipdata[i][ABIL_DESTCAP],
  593. X                        Shipdata[i][ABIL_GUNS],
  594. X                        Shipdata[i][ABIL_PRIMARY],
  595. X                        Shipdata[i][ABIL_SECONDARY],
  596. X                        Shipdata[i][ABIL_FUELCAP],
  597. X                        Shipdata[i][ABIL_MAXCREW],
  598. X                        Shipdata[i][ABIL_SPEED],
  599. X                        (double) Shipdata[i][ABIL_TECH],
  600. X                        Shipcost(i, Race));
  601. X                    strcat(buf, temp);
  602. X                    notify(Playernum, Governor, buf);
  603. X                }
  604. X            }
  605. X        }
  606. X        return;
  607. X    }
  608. X    level = Dir[Playernum - 1][Governor].level;
  609. X    if (level != LEVEL_SHIP && level != LEVEL_PLAN) {
  610. X        notify(Playernum, Governor, "You must change scope to a ship or planet to build.\n");
  611. X        return;
  612. X    }
  613. X    snum = Dir[Playernum - 1][Governor].snum;
  614. X    pnum = Dir[Playernum - 1][Governor].pnum;
  615. X    Race = races[Playernum - 1];
  616. X    count = 0;        /* this used used to reset count in the loop */
  617. X    do {
  618. X        switch (level) {
  619. X        case LEVEL_PLAN:
  620. X            if (!count) {    /* initialize loop variables */
  621. X                if (argn < 2) {
  622. X                    notify(Playernum, Governor, "Build what?\n");
  623. X                    return;
  624. X                }
  625. X                if ((what = get_build_type(args[1])) < 0) {
  626. X                    notify(Playernum, Governor, "No such ship type.\n");
  627. X                    return;
  628. X                }
  629. X                if (!can_build_this(what, Race, buf) && !Race->God) {
  630. X                    notify(Playernum, Governor, buf);
  631. X                    return;
  632. X                }
  633. X                if (!(Shipdata[what][ABIL_BUILD] & 1) && !Race->God) {
  634. X                    notify(Playernum, Governor, "This ship cannot be built by a planet.\n");
  635. X                    return;
  636. X                }
  637. X                if (argn < 3) {
  638. X                    notify(Playernum, Governor, "Build where?\n");
  639. X                    return;
  640. X                }
  641. X                getplanet(&planet, snum, pnum);
  642. X                if (!can_build_at_planet(Playernum, Governor, Stars[snum], planet) && !Race->God) {
  643. X                    notify(Playernum, Governor, "You can't build that here.\n");
  644. X                    free(planet);
  645. X                    return;
  646. X                }
  647. X                sscanf(args[2], "%d,%d", &x, &y);
  648. X                if (x < 0 || x >= planet->Maxx || y < 0 || y >= planet->Maxy) {
  649. X                    notify(Playernum, Governor, "Illegal sector.\n");
  650. X                    free(planet);
  651. X                    return;
  652. X                }
  653. X                getsector(§or, planet, x, y);
  654. X                if (!can_build_on_sector(what, Race, planet, sector, x, y, buf) && !Race->God) {
  655. X                    notify(Playernum, Governor, buf);
  656. X                    free(planet);
  657. X                    free(sector);
  658. X                    return;
  659. X                }
  660. X                if (!(count = getcount(argn < 4, args[3]))) {
  661. X                    notify(Playernum, Governor,
  662. X                           "Give a positive number of builds.\n");
  663. X                    free(planet);
  664. X                    free(sector);
  665. X                    return;
  666. X                }
  667. X                Getship(&newship, what, Race);
  668. X            }
  669. X            if ((shipcost = newship.build_cost) >
  670. X                planet->info[Playernum - 1].resource) {
  671. X                sprintf(buf, "You need %dr to construct this ship.\n", shipcost);
  672. X                notify(Playernum, Governor, buf);
  673. X                goto finish;
  674. X            }
  675. X            create_ship_by_planet(Playernum, Governor, Race, &newship, planet, snum, pnum, x, y);
  676. X            if (Race->governor[Governor].toggle.autoload &&
  677. X                what != OTYPE_TRANSDEV && !Race->God)
  678. X                autoload_at_planet(Playernum, &newship, planet, sector, &load_crew, &load_fuel);
  679. X            else {
  680. X                load_crew = 0;
  681. X                load_fuel = 0.0;
  682. X            }
  683. X            initialize_new_ship(Playernum, Governor, Race, &newship, load_fuel, load_crew);
  684. X            putship(&newship);
  685. X            break;
  686. X        case LEVEL_SHIP:
  687. X            if (!count) {    /* initialize loop variables */
  688. X                (void) getship(&builder, Dir[Playernum - 1][Governor].shipno);
  689. X                outside = 0;
  690. X                if ((build_level = build_at_ship(Playernum, Governor, Race,
  691. X                          builder, &snum, &pnum)) < 0) {
  692. X                    notify(Playernum, Governor, "You can't build here.\n");
  693. X                    free(builder);
  694. X                    return;
  695. X                }
  696. X                switch (builder->type) {
  697. X                case OTYPE_FACTORY:
  698. X                    if (!(count = getcount(argn < 2, args[1]))) {
  699. X                        notify(Playernum, Governor,
  700. X                               "Give a positive number of builds.\n");
  701. X                        free(builder);
  702. X                        return;
  703. X                    }
  704. X                    if (!landed(builder)) {
  705. X                        notify(Playernum, Governor, "Factories can only build when landed on a planet.\n");
  706. X                        free(builder);
  707. X                        return;
  708. X                    }
  709. X                    Getfactship(&newship, builder);
  710. X                    outside = 1;
  711. X                    break;
  712. X                case STYPE_SHUTTLE:
  713. X                case STYPE_CARGO:
  714. X                    if (landed(builder)) {
  715. X                        notify(Playernum, Governor, "This ships cannot build when landed.\n");
  716. X                        free(builder);
  717. X                        return;
  718. X                    }
  719. X                    outside = 1;
  720. X                default:
  721. X                    if (argn < 2) {
  722. X                        notify(Playernum, Governor, "Build what?\n");
  723. X                        free(builder);
  724. X                        return;
  725. X                    }
  726. X                    if ((what = get_build_type(args[1])) < 0) {
  727. X                        notify(Playernum, Governor, "No such ship type.\n");
  728. X                        free(builder);
  729. X                        return;
  730. X                    }
  731. X                    if (!can_build_on_ship(what, Race, builder, buf)) {
  732. X                        notify(Playernum, Governor, buf);
  733. X                        free(builder);
  734. X                        return;
  735. X                    }
  736. X                    if (!(count = getcount(argn < 3, args[2]))) {
  737. X                        notify(Playernum, Governor,
  738. X                               "Give a positive number of builds.\n");
  739. X                        free(builder);
  740. X                        return;
  741. X                    }
  742. X                    Getship(&newship, what, Race);
  743. X                    break;
  744. X                }
  745. X                if ((tech = builder->type == OTYPE_FACTORY ? complexity(builder) :
  746. X                     Shipdata[what][ABIL_TECH]) > Race->tech && !Race->God) {
  747. X                    sprintf(buf, "You are not advanced enough to build this ship.\n%.1f enginering technology needed. You have %.1f.\n",
  748. X                        tech, Race->tech);
  749. X                    notify(Playernum, Governor, buf);
  750. X                    free(builder);
  751. X                    return;
  752. X                }
  753. X                if (outside && build_level == LEVEL_PLAN) {
  754. X                    getplanet(&planet, snum, pnum);
  755. X                    if (builder->type == OTYPE_FACTORY) {
  756. X                        if (!can_build_at_planet(Playernum, Governor, Stars[snum], planet)) {
  757. X                            notify(Playernum, Governor, "You can't build that here.\n");
  758. X                            free(planet);
  759. X                            free(builder);
  760. X                            return;
  761. X                        }
  762. X                        x = builder->land_x;
  763. X                        y = builder->land_y;
  764. X                        what = builder->build_type;
  765. X                        getsector(§or, planet, x, y);
  766. X                        if (!can_build_on_sector(what, Race, planet, sector, x, y, buf)) {
  767. X                            notify(Playernum, Governor, buf);
  768. X                            free(planet);
  769. X                            free(sector);
  770. X                            free(builder);
  771. X                            return;
  772. X                        }
  773. X                    }
  774. X                }
  775. X            }
  776. X            /* build 'em */
  777. X            switch (builder->type) {
  778. X            case OTYPE_FACTORY:
  779. X                if ((shipcost = newship.build_cost) >
  780. X                    planet->info[Playernum - 1].resource) {
  781. X                    sprintf(buf, "You need %dr to construct this ship.\n", shipcost);
  782. X                    notify(Playernum, Governor, buf);
  783. X                    goto finish;
  784. X                }
  785. X                create_ship_by_planet(Playernum, Governor, Race, &newship, planet, snum, pnum, x, y);
  786. X                if (Race->governor[Governor].toggle.autoload &&
  787. X                    what != OTYPE_TRANSDEV && !Race->God) {
  788. X                    autoload_at_planet(Playernum, &newship, planet, sector, &load_crew, &load_fuel);
  789. X                } else {
  790. X                    load_crew = 0;
  791. X                    load_fuel = 0.0;
  792. X                }
  793. X                break;
  794. X            case STYPE_SHUTTLE:
  795. X            case STYPE_CARGO:
  796. X                if (builder->resource < (shipcost = newship.build_cost)) {
  797. X                    sprintf(buf, "You need %dr to construct the ship.\n", shipcost);
  798. X                    notify(Playernum, Governor, buf);
  799. X                    goto finish;
  800. X                }
  801. X                create_ship_by_ship(Playernum, Governor, Race, 1,
  802. X                            Stars[builder->storbits], planet, &newship, builder);
  803. X                if (Race->governor[Governor].toggle.autoload &&
  804. X                    what != OTYPE_TRANSDEV && !Race->God)
  805. X                    autoload_at_ship(Playernum, &newship, builder, &load_crew, &load_fuel);
  806. X                else {
  807. X                    load_crew = 0;
  808. X                    load_fuel = 0.0;
  809. X                }
  810. X                break;
  811. X            default:
  812. X                if (builder->hanger + ship_size(&newship) > builder->max_hanger) {
  813. X                    notify(Playernum, Governor, "Not enough hanger space.\n");
  814. X                    goto finish;
  815. X                }
  816. X                if (builder->resource < (shipcost = newship.build_cost)) {
  817. X                    sprintf(buf, "You need %dr to construct the ship.\n", shipcost);
  818. X                    notify(Playernum, Governor, buf);
  819. X                    goto finish;
  820. X                }
  821. X                create_ship_by_ship(Playernum, Governor, Race, 0,
  822. X                         NULL, NULL, &newship, builder);
  823. X                if (Race->governor[Governor].toggle.autoload &&
  824. X                    what != OTYPE_TRANSDEV && !Race->God)
  825. X                    autoload_at_ship(Playernum, &newship, builder, &load_crew, &load_fuel);
  826. X                else {
  827. X                    load_crew = 0;
  828. X                    load_fuel = 0.0;
  829. X                }
  830. X                break;
  831. X            }
  832. X            initialize_new_ship(Playernum, Governor, Race, &newship, load_fuel, load_crew);
  833. X            putship(&newship);
  834. X            break;
  835. X        }
  836. X        count--;
  837. X    } while (count);
  838. X    /* free stuff */
  839. Xfinish:
  840. X    switch (level) {
  841. X    case LEVEL_PLAN:
  842. X        putsector(sector, planet, x, y);
  843. X        putplanet(planet, snum, pnum);
  844. X        free(sector);
  845. X        free(planet);
  846. X        break;
  847. X    case LEVEL_SHIP:
  848. X        if (outside)
  849. X            switch (build_level) {
  850. X            case LEVEL_PLAN:
  851. X                putplanet(planet, snum, pnum);
  852. X                if (landed(builder)) {
  853. X                    putsector(sector, planet, x, y);
  854. X                    free(sector);
  855. X                }
  856. X                free(planet);
  857. X                break;
  858. X            case LEVEL_STAR:
  859. X                putstar(Stars[snum], snum);
  860. X                break;
  861. X            case LEVEL_UNIV:
  862. X                putsdata(&Sdata);
  863. X                break;
  864. X            }
  865. X        putship(builder);
  866. X        free(builder);
  867. X        break;
  868. X    }
  869. X}
  870. X
  871. Xint 
  872. Xgetcount(int mode, char *string)
  873. X{
  874. X    int             count;
  875. X
  876. X    if (mode)
  877. X        count = 1;
  878. X    else
  879. X        count = atoi(string);
  880. X    if (count <= 0)
  881. X        count = 0;
  882. X
  883. X    return (count);
  884. X}
  885. X
  886. Xint 
  887. Xcan_build_at_planet(int Playernum, int Governor, startype * star,
  888. X            planettype * planet)
  889. X{
  890. X    if (planet->slaved_to && planet->slaved_to != Playernum) {
  891. X        sprintf(buf, "This planet is enslaved by player %d.\n", planet->slaved_to);
  892. X        notify(Playernum, Governor, buf);
  893. X        return (0);
  894. X    }
  895. X    if (Governor && star->governor[Playernum - 1] != Governor) {
  896. X        notify(Playernum, Governor, "You are not authorized in this system.\n");
  897. X        return (0);
  898. X    }
  899. X    return (1);
  900. X}
  901. X
  902. Xint 
  903. Xget_build_type(char *string)
  904. X{
  905. X    char            shipc;
  906. X    reg int         i = 0;
  907. X
  908. X    shipc = string[0];
  909. X    while (i < NUMSTYPES && Shipltrs[i] != shipc)
  910. X        i++;
  911. X    if (i < 0 || i >= NUMSTYPES)
  912. X        return (-1);
  913. X    return i;
  914. X}
  915. X
  916. Xint 
  917. Xcan_build_this(int what, racetype * Race, char *string)
  918. X{
  919. X    if (what == STYPE_POD && !Race->pods) {
  920. X        sprintf(string, "Only Metamorphic races can build Spore Pods.\n");
  921. X        return (0);
  922. X    }
  923. X    if (!Shipdata[what][ABIL_PROGRAMMED]) {
  924. X        sprintf(string, "This ship type has not been programmed.\n");
  925. X        return (0);
  926. X    }
  927. X    if (what == OTYPE_TRANSDEV && !Avpm(Race)) {
  928. X        sprintf(string, "You have not discovered AVPM technology.\n");
  929. X        return (0);
  930. X    }
  931. X    if (Shipdata[what][ABIL_TECH] > Race->tech && !Race->God) {
  932. X        sprintf(string, "You are not advanced enough to build this ship.\n%.1f enginering technology needed. You have %.1f.\n",
  933. X            (double) Shipdata[what][ABIL_TECH], Race->tech);
  934. X        return (0);
  935. X    }
  936. X    return 1;
  937. X}
  938. X
  939. Xint 
  940. Xcan_build_on_ship(int what, racetype * Race, shiptype * builder,
  941. X          char *string)
  942. X{
  943. X    if (!(Shipdata[what][ABIL_BUILD] &
  944. X          Shipdata[builder->type][ABIL_CONSTRUCT]) && !Race->God) {
  945. X        sprintf(string, "This ship type cannot be built by a %s.\n",
  946. X            Shipnames[builder->type]);
  947. X        sprintf(temp, "Use 'build ? %c' to find out where it can be built.\n", Shipltrs[what]);
  948. X        strcat(string, temp);
  949. X        return (0);
  950. X    }
  951. X    return (1);
  952. X}
  953. X
  954. Xint 
  955. Xcan_build_on_sector(int what, racetype * Race, planettype * planet,
  956. X            sectortype * sector, int x, int y, char *string)
  957. X{
  958. X    shiptype       *s;
  959. X    char            shipc;
  960. X
  961. X    shipc = Shipltrs[what];
  962. X    if (!sector->popn) {
  963. X        sprintf(string, "You have no more civs in the sector!\n");
  964. X        return (0);
  965. X    }
  966. X    if (sector->condition == WASTED) {
  967. X        sprintf(string, "You can't build on wasted sectors.\n");
  968. X        return (0);
  969. X    }
  970. X    if (sector->owner != Race->Playernum && !Race->God) {
  971. X        sprintf(string, "You don't own that sector.\n");
  972. X        return (0);
  973. X    }
  974. X    if ((!Shipdata[what][ABIL_BUILD] & 1) && !Race->God) {
  975. X        sprintf(string, "This ship type cannot be built on a planet.\n");
  976. X        sprintf(temp, "Use 'build ? %c' to find out where it can be built.\n", shipc);
  977. X        strcat(string, temp);
  978. X        return (0);
  979. X    }
  980. X    if (what == OTYPE_QUARRY) {
  981. X        reg int         sh;
  982. X        sh = planet->ships;
  983. X        while (sh) {
  984. X            (void) getship(&s, sh);
  985. X            if (s->alive && s->type == OTYPE_QUARRY &&
  986. X                s->land_x == x && s->land_y == y) {
  987. X                sprintf(string, "There already is a quarry here.\n");
  988. X                free(s);
  989. X                return (0);
  990. X            }
  991. X            sh = s->nextship;
  992. X            free(s);
  993. X        }
  994. X    }
  995. X    return (1);
  996. X}
  997. X
  998. Xint 
  999. Xbuild_at_ship(int Playernum, int Governor, racetype * Race,
  1000. X          shiptype * builder, int *snum, int *pnum)
  1001. X{
  1002. X    if (testship(Playernum, Governor, builder))
  1003. X        return (-1);
  1004. X    if (!Shipdata[builder->type][ABIL_CONSTRUCT]) {
  1005. X        notify(Playernum, Governor, "This ship cannot construct other ships.\n");
  1006. X        return (-1);
  1007. X    }
  1008. X    if (!builder->popn) {
  1009. X        notify(Playernum, Governor, "This ship has no crew.\n");
  1010. X        return (-1);
  1011. X    }
  1012. X    if (docked(builder)) {
  1013. X        notify(Playernum, Governor, "Undock this ship first.\n");
  1014. X        return (-1);
  1015. X    }
  1016. X    if (builder->damage) {
  1017. X        notify(Playernum, Governor, "This ship is damaged and cannot build.\n");
  1018. X        return (-1);
  1019. X    }
  1020. X    if (builder->type == OTYPE_FACTORY && !builder->on) {
  1021. X        notify(Playernum, Governor, "This factory is not online.\n");
  1022. X        return (-1);
  1023. X    }
  1024. X    if (builder->type == OTYPE_FACTORY && !landed(builder)) {
  1025. X        notify(Playernum, Governor, "Factories must be landed on a planet.\n");
  1026. X        return (-1);
  1027. X    }
  1028. X    *snum = builder->storbits;
  1029. X    *pnum = builder->pnumorbits;
  1030. X    return (builder->whatorbits);
  1031. X}
  1032. X
  1033. Xvoid 
  1034. Xautoload_at_planet(int Playernum, shiptype * s, planettype * planet,
  1035. X           sectortype * sector, int *crew, double *fuel)
  1036. X{
  1037. X    *crew = MIN(s->max_crew, sector->popn);
  1038. X    *fuel = MIN((double) s->max_fuel, (double) planet->info[Playernum - 1].fuel);
  1039. X    sector->popn -= *crew;
  1040. X    if (!sector->popn && !sector->troops)
  1041. X        sector->owner = 0;
  1042. X    planet->info[Playernum - 1].fuel -= (int) (*fuel);
  1043. X}
  1044. X
  1045. Xvoid 
  1046. Xautoload_at_ship(int Playernum, shiptype * s, shiptype * b, int *crew,
  1047. X         double *fuel)
  1048. X{
  1049. X    *crew = MIN(s->max_crew, b->popn);
  1050. X    *fuel = MIN((double) s->max_fuel, (double) b->fuel);
  1051. X    b->popn -= *crew;
  1052. X    b->fuel -= *fuel;
  1053. X}
  1054. X
  1055. Xvoid 
  1056. Xinitialize_new_ship(int Playernum, int Governor, racetype * Race,
  1057. X            shiptype * newship, double load_fuel, int load_crew)
  1058. X{
  1059. X#ifdef AUTOSCRAP 
  1060. X    newship->autoscrap = 0;
  1061. X#endif
  1062. X#ifdef THRESHLOADING
  1063. X    newship->threshload[RESOURCE] = 0;
  1064. X    newship->threshload[DESTRUCT] = 0;
  1065. X    newship->threshload[FUEL] = 0;
  1066. X    newship->threshload[CRYSTAL] = 0;
  1067. X#endif 
  1068. X    newship->speed = newship->max_speed;
  1069. X    newship->owner = Playernum;
  1070. X    newship->governor = Governor;
  1071. X    newship->fuel = Race->God ? newship->max_fuel : load_fuel;
  1072. X    newship->popn = Race->God ? newship->max_crew : load_crew;
  1073. X    newship->troops = 0;
  1074. X    newship->resource = Race->God ? newship->max_resource : 0;
  1075. X    newship->destruct = Race->God ? newship->max_destruct : 0;
  1076. X    newship->crystals = 0;
  1077. X    newship->hanger = 0;
  1078. X    newship->mass = newship->base_mass +
  1079. X        (double) newship->popn * Race->mass +
  1080. X        (double) newship->fuel * MASS_FUEL +
  1081. X        (double) newship->resource * MASS_RESOURCE +
  1082. X        (double) newship->destruct * MASS_DESTRUCT;
  1083. X    newship->alive = 1;
  1084. X    newship->active = 1;
  1085. X    newship->protect.self = newship->guns ? 1 : 0;
  1086. X    newship->hyper_drive.on = 0;
  1087. X    newship->hyper_drive.ready = 0;
  1088. X    newship->hyper_drive.charge = 0;
  1089. X    newship->mounted = Race->God ? newship->mount : 0;
  1090. X    newship->cloak = 0;
  1091. X    newship->cloaked = 0;
  1092. X    newship->fire_laser = 0;
  1093. X    newship->mode = 0;
  1094. X    newship->rad = 0;
  1095. X    newship->damage = Race->God ? 0 : Shipdata[newship->type][ABIL_DAMAGE];
  1096. X    newship->retaliate = newship->primary;
  1097. X    newship->ships = 0;
  1098. X    newship->on = 0;
  1099. X    switch (newship->type) {
  1100. X    case STYPE_MINE:
  1101. X        newship->special.trigger.radius = 100;    /* trigger radius */
  1102. X        notify(Playernum, Governor, "Mine disarmed.\nTrigger radius set at 100.\n");
  1103. X        break;
  1104. X    case OTYPE_TRANSDEV:
  1105. X        newship->special.transport.target = 0;
  1106. X        newship->on = 0;
  1107. X        notify(Playernum, Governor, "Receive OFF.  Change with order.\n");
  1108. X        break;
  1109. X    case OTYPE_AP:
  1110. X        notify(Playernum, Governor, "Processor OFF.\n");
  1111. X        break;
  1112. X    case OTYPE_STELE:
  1113. X    case OTYPE_GTELE:
  1114. X        sprintf(buf, "Telescope range is %.2f.\n",
  1115. X            tele_range(newship->type, newship->tech));
  1116. X        notify(Playernum, Governor, buf);
  1117. X        break;
  1118. X    default:
  1119. X        break;
  1120. X    }
  1121. X    if (newship->damage) {
  1122. X        sprintf(buf,
  1123. X            "Warning: This ship is constructed with a %d%% damage level.\n",
  1124. X            newship->damage);
  1125. X        notify(Playernum, Governor, buf);
  1126. X        if (!Shipdata[newship->type][ABIL_REPAIR] && newship->max_crew)
  1127. X            notify(Playernum, Governor,
  1128. X                   "It will need resources to become fully operational.\n");
  1129. X    }
  1130. X    if (Shipdata[newship->type][ABIL_REPAIR] && newship->max_crew)
  1131. X        notify(Playernum, Governor, "This ship does not need resources to repair.\n");
  1132. X    if (newship->type == OTYPE_FACTORY)
  1133. X        notify(Playernum, Governor,
  1134. X               "This factory may not begin repairs until it has been activated.\n");
  1135. X    if (!newship->max_crew)
  1136. X        notify(Playernum, Governor, "This ship is robotic, and may not repair itself.\n");
  1137. X    sprintf(buf, "Loaded with %d crew and %.1f fuel.\n", load_crew, load_fuel);
  1138. X    notify(Playernum, Governor, buf);
  1139. X}
  1140. X
  1141. Xvoid 
  1142. Xcreate_ship_by_planet(int Playernum, int Governor, racetype * Race,
  1143. X              shiptype * newship, planettype * planet, int snum,
  1144. X              int pnum, int x, int y)
  1145. X{
  1146. X    int             shipno;
  1147. X
  1148. X    newship->tech = Race->tech;
  1149. X    newship->xpos = Stars[snum]->xpos + planet->xpos;
  1150. X    newship->ypos = Stars[snum]->ypos + planet->ypos;
  1151. X    newship->land_x = x;
  1152. X    newship->land_y = y;
  1153. X    sprintf(newship->class, (((newship->type == OTYPE_TERRA) ||
  1154. X            (newship->type == OTYPE_PLOW)) ? "5" : "Standard"));
  1155. X    newship->whatorbits = LEVEL_PLAN;
  1156. X    newship->whatdest = LEVEL_PLAN;
  1157. X    newship->deststar = snum;
  1158. X    newship->destpnum = pnum;
  1159. X    newship->storbits = snum;
  1160. X    newship->pnumorbits = pnum;
  1161. X    newship->docked = 1;
  1162. X    planet->info[Playernum - 1].resource -= newship->build_cost;
  1163. X    while ((shipno = getdeadship()) == 0);
  1164. X    if (shipno == -1)
  1165. X        shipno = Numships() + 1;
  1166. X    newship->number = shipno;
  1167. X    newship->owner = Playernum;
  1168. X    newship->governor = Governor;
  1169. X    newship->ships = 0;
  1170. X    insert_sh_plan(planet, newship);
  1171. X    if (newship->type == OTYPE_TOXWC) {
  1172. X        sprintf(buf, "Toxin concentration on planet was %d%%,",
  1173. X            planet->conditions[TOXIC]);
  1174. X        notify(Playernum, Governor, buf);
  1175. X        if (planet->conditions[TOXIC] > TOXMAX)
  1176. X            newship->special.waste.toxic = TOXMAX;
  1177. X        else
  1178. X            newship->special.waste.toxic = planet->conditions[TOXIC];
  1179. X        planet->conditions[TOXIC] -= newship->special.waste.toxic;
  1180. X        sprintf(buf, " now %d%%.\n", planet->conditions[TOXIC]);
  1181. X        notify(Playernum, Governor, buf);
  1182. X    }
  1183. X    sprintf(buf, "%s built at a cost of %d resources.\n",
  1184. X        Ship(newship), newship->build_cost);
  1185. X    notify(Playernum, Governor, buf);
  1186. X    sprintf(buf, "Technology %.1f.\n", newship->tech);
  1187. X    notify(Playernum, Governor, buf);
  1188. X    sprintf(buf, "%s is on sector %d,%d.\n",
  1189. X        Ship(newship), newship->land_x, newship->land_y);
  1190. X    notify(Playernum, Governor, buf);
  1191. X}
  1192. X
  1193. Xvoid 
  1194. Xcreate_ship_by_ship(int Playernum, int Governor, racetype * Race,
  1195. X            int outside, startype * star, planettype * planet,
  1196. X            shiptype * newship, shiptype * builder)
  1197. X{
  1198. X    int             shipno;
  1199. X
  1200. X    while ((shipno = getdeadship()) == 0);
  1201. X    if (shipno == -1)
  1202. X        shipno = Numships() + 1;
  1203. X    newship->number = shipno;
  1204. X    newship->owner = Playernum;
  1205. X    newship->governor = Governor;
  1206. X    if (outside) {
  1207. X        newship->whatorbits = builder->whatorbits;
  1208. X        newship->whatdest = LEVEL_UNIV;
  1209. X        newship->deststar = builder->deststar;
  1210. X        newship->destpnum = builder->destpnum;
  1211. X        newship->storbits = builder->storbits;
  1212. X        newship->pnumorbits = builder->pnumorbits;
  1213. X        newship->docked = 0;
  1214. X        switch (builder->whatorbits) {
  1215. X        case LEVEL_PLAN:
  1216. X            insert_sh_plan(planet, newship);
  1217. X            break;
  1218. X        case LEVEL_STAR:
  1219. X            insert_sh_star(Stars[builder->storbits], newship);
  1220. X            break;
  1221. X        case LEVEL_UNIV:
  1222. X            insert_sh_univ(&Sdata, newship);
  1223. X            break;
  1224. X        }
  1225. X    } else {
  1226. X        newship->whatorbits = LEVEL_SHIP;
  1227. X        newship->whatdest = LEVEL_SHIP;
  1228. X        newship->deststar = builder->deststar;
  1229. X        newship->destpnum = builder->destpnum;
  1230. X        newship->destshipno = builder->number;
  1231. X        newship->storbits = builder->storbits;
  1232. X        newship->pnumorbits = builder->pnumorbits;
  1233. X        newship->docked = 1;
  1234. X        insert_sh_ship(newship, builder);
  1235. X    }
  1236. X    newship->tech = Race->tech;
  1237. X    newship->xpos = builder->xpos;
  1238. X    newship->ypos = builder->ypos;
  1239. X    newship->land_x = builder->land_x;
  1240. X    newship->land_y = builder->land_y;
  1241. X    sprintf(newship->class, (((newship->type == OTYPE_TERRA) ||
  1242. X            (newship->type == OTYPE_PLOW)) ? "5" : "Standard"));
  1243. X    builder->resource -= newship->build_cost;
  1244. X
  1245. X    sprintf(buf, "%s built at a cost of %d resources.\n",
  1246. X        Ship(newship), newship->build_cost);
  1247. X    notify(Playernum, Governor, buf);
  1248. X    sprintf(buf, "Technology %.1f.\n", newship->tech);
  1249. X    notify(Playernum, Governor, buf);
  1250. X}
  1251. X
  1252. Xdouble 
  1253. Xgetmass(shiptype * s)
  1254. X{
  1255. X    return (1.0 + MASS_ARMOR * s->armor
  1256. X        + MASS_SIZE * (s->size - s->max_hanger)
  1257. X        + MASS_HANGER * s->max_hanger
  1258. X        + MASS_GUNS * s->primary * s->primtype
  1259. X        + MASS_GUNS * s->secondary * s->sectype);
  1260. X}
  1261. X
  1262. Xint 
  1263. Xship_size(shiptype * s)
  1264. X{
  1265. X    double          size;
  1266. X    size = 1.0 + SIZE_GUNS * s->primary
  1267. X        + SIZE_GUNS * s->secondary
  1268. X        + SIZE_CREW * s->max_crew
  1269. X        + SIZE_RESOURCE * s->max_resource
  1270. X        + SIZE_FUEL * s->max_fuel
  1271. X        + SIZE_DESTRUCT * s->max_destruct
  1272. X        + s->max_hanger;
  1273. X    return ((int) size);
  1274. X}
  1275. X
  1276. Xdouble 
  1277. Xcost(shiptype * s)
  1278. X{
  1279. X    int             i;
  1280. X    double          factor = 0.0, advantage = 0.0;
  1281. X
  1282. X    i = s->build_type;
  1283. X    /* compute how much it costs to build this ship */
  1284. X    factor += (double) Shipdata[i][ABIL_COST];
  1285. X    factor += GUN_COST * (double) s->primary;
  1286. X    factor += GUN_COST * (double) s->secondary;
  1287. X    factor += CREW_COST * (double) s->max_crew;
  1288. X    factor += CARGO_COST * (double) s->max_resource;
  1289. X    factor += FUEL_COST * (double) s->max_fuel;
  1290. X    factor += AMMO_COST * (double) s->max_destruct;
  1291. X    factor += SPEED_COST * (double) s->max_speed * (double) sqrt((double) s->max_speed);
  1292. X    factor += HANGER_COST * (double) s->max_hanger;
  1293. X    factor += ARMOR_COST * (double) s->armor * (double) sqrt((double) s->armor);
  1294. X    factor += CEW_COST * (double) (s->cew * s->cew_range);
  1295. X    /* additional advantages/disadvantages */
  1296. X
  1297. X    advantage += 0.5 * !!s->hyper_drive.has;
  1298. X    advantage += 0.5 * !!s->laser;
  1299. X    advantage += 0.5 * !!s->cloak;
  1300. X    advantage += 0.5 * !!s->mount;
  1301. X
  1302. X    factor *= sqrt(1.0 + advantage);
  1303. X    return (factor);
  1304. X
  1305. X}
  1306. X
  1307. Xvoid 
  1308. Xsystem_cost(double *advantage, double *disadvantage, int value, int base)
  1309. X{
  1310. X    double          factor;
  1311. X
  1312. X    factor = (((double) value + 1.0) / (base + 1.0)) - 1.0;
  1313. X    if (factor >= 0.0)
  1314. X        *advantage += factor;
  1315. X    else
  1316. X        *disadvantage -= factor;
  1317. X}
  1318. X
  1319. Xdouble 
  1320. Xcomplexity(shiptype * s)
  1321. X{
  1322. X    int             i;
  1323. X    double          advantage, disadvantage, factor, temp;
  1324. X
  1325. X    i = s->build_type;
  1326. X
  1327. X    advantage = 0.;
  1328. X    disadvantage = 0.;
  1329. X
  1330. X    system_cost(&advantage, &disadvantage, (int) (s->primary),
  1331. X            Shipdata[i][ABIL_GUNS]);
  1332. X    system_cost(&advantage, &disadvantage, (int) (s->secondary),
  1333. X            Shipdata[i][ABIL_GUNS]);
  1334. X    system_cost(&advantage, &disadvantage, (int) (s->max_crew),
  1335. X            Shipdata[i][ABIL_MAXCREW]);
  1336. X    system_cost(&advantage, &disadvantage, (int) (s->max_resource),
  1337. X            Shipdata[i][ABIL_CARGO]);
  1338. X    system_cost(&advantage, &disadvantage, (int) (s->max_fuel),
  1339. X            Shipdata[i][ABIL_FUELCAP]);
  1340. X    system_cost(&advantage, &disadvantage, (int) (s->max_destruct),
  1341. X            Shipdata[i][ABIL_DESTCAP]);
  1342. X    system_cost(&advantage, &disadvantage, (int) (s->max_speed),
  1343. X            Shipdata[i][ABIL_SPEED]);
  1344. X    system_cost(&advantage, &disadvantage, (int) (s->max_hanger),
  1345. X            Shipdata[i][ABIL_HANGER]);
  1346. X    system_cost(&advantage, &disadvantage, (int) (s->armor),
  1347. X            Shipdata[i][ABIL_ARMOR]);
  1348. X    /* additional advantages/disadvantages */
  1349. X
  1350. X    factor = sqrt((1.0 + advantage) * exp(-(double) disadvantage / 10.0));
  1351. X    temp = COMPLEXITY_FACTOR * (factor - 1.0) / sqrt((double) (Shipdata[i][ABIL_TECH] + 1)) + 1.0;
  1352. X    factor = temp * temp;
  1353. X    return (factor * (double) Shipdata[i][ABIL_TECH]);
  1354. X}
  1355. X
  1356. Xvoid 
  1357. XGetship(shiptype * s, int i, racetype * r)
  1358. X{
  1359. X    bzero((char *) s, sizeof(shiptype));
  1360. X    s->type = i;
  1361. X    s->armor = Shipdata[i][ABIL_ARMOR];
  1362. X    s->guns = Shipdata[i][ABIL_PRIMARY] ? PRIMARY : NONE;
  1363. X    s->primary = Shipdata[i][ABIL_GUNS];
  1364. X    s->primtype = Shipdata[i][ABIL_PRIMARY];
  1365. X    s->secondary = Shipdata[i][ABIL_GUNS];
  1366. X    s->sectype = Shipdata[i][ABIL_SECONDARY];
  1367. X    s->max_crew = Shipdata[i][ABIL_MAXCREW];
  1368. X    s->max_resource = Shipdata[i][ABIL_CARGO];
  1369. X    s->max_hanger = Shipdata[i][ABIL_HANGER];
  1370. X    s->max_destruct = Shipdata[i][ABIL_DESTCAP];
  1371. X    s->max_fuel = Shipdata[i][ABIL_FUELCAP];
  1372. X    s->max_speed = Shipdata[i][ABIL_SPEED];
  1373. X    s->build_type = i;
  1374. X    s->mount = r->God ? Shipdata[i][ABIL_MOUNT] : 0;
  1375. X    s->hyper_drive.has = r->God ? Shipdata[i][ABIL_JUMP] : 0;
  1376. X    s->cloak = 0;
  1377. X    s->laser = r->God ? Shipdata[i][ABIL_LASER] : 0;
  1378. X    s->cew = 0;
  1379. X    s->cew_range = 0;
  1380. X    s->size = ship_size(s);
  1381. X    s->base_mass = getmass(s);
  1382. X    s->mass = getmass(s);
  1383. X    s->build_cost = r->God ? 0 : (int) cost(s);
  1384. X}
  1385. X
  1386. Xvoid 
  1387. XGetfactship(shiptype * s, shiptype * b)
  1388. X{
  1389. X    bzero((char *) s, sizeof(shiptype));
  1390. X    s->type = b->build_type;
  1391. X    s->armor = b->armor;
  1392. X    s->primary = b->primary;
  1393. X    s->primtype = b->primtype;
  1394. X    s->secondary = b->secondary;
  1395. X    s->sectype = b->sectype;
  1396. X    s->guns = s->primary ? PRIMARY : NONE;
  1397. X    s->max_crew = b->max_crew;
  1398. X    s->max_resource = b->max_resource;
  1399. X    s->max_hanger = b->max_hanger;
  1400. X    s->max_destruct = b->max_destruct;
  1401. X    s->max_fuel = b->max_fuel;
  1402. X    s->max_speed = b->max_speed;
  1403. X    s->build_type = b->build_type;
  1404. X    s->build_cost = b->build_cost;
  1405. X    s->mount = b->mount;
  1406. X    s->hyper_drive.has = b->hyper_drive.has;
  1407. X    s->cloak = 0;
  1408. X    s->laser = b->laser;
  1409. X    s->cew = b->cew;
  1410. X    s->cew_range = b->cew_range;
  1411. X    s->size = ship_size(s);
  1412. X    s->base_mass = getmass(s);
  1413. X    s->mass = getmass(s);
  1414. X}
  1415. X
  1416. Xint 
  1417. XShipcost(int i, racetype * r)
  1418. X{
  1419. X    shiptype        s;
  1420. X
  1421. X    Getship(&s, i, r);
  1422. X    return ((int) cost(&s));
  1423. X}
  1424. X
  1425. X#ifdef MARKET
  1426. Xchar           *Commod[] = {"resources", "destruct", "fuel", "crystals"};
  1427. X
  1428. Xvoid 
  1429. Xsell(int Playernum, int Governor, int APcount)
  1430. X{
  1431. X    racetype       *Race;
  1432. X    planettype     *p;
  1433. X    shiptype       *s;
  1434. X    commodtype      c;
  1435. X    int             commodno, amount, item, ok = 0, sh;
  1436. X    char            commod;
  1437. X    int             snum, pnum;
  1438. X    reg int         i;
  1439. X
  1440. X    if (Dir[Playernum - 1][Governor].level != LEVEL_PLAN) {
  1441. X        notify(Playernum, Governor, "You have to be in a planet scope to sell.\n");
  1442. X        return;
  1443. X    }
  1444. X    snum = Dir[Playernum - 1][Governor].snum;
  1445. X    pnum = Dir[Playernum - 1][Governor].pnum;
  1446. X    if (argn < 3) {
  1447. X        notify(Playernum, Governor, "Syntax: sell <commodity> <amount>\n");
  1448. X        return;
  1449. X    }
  1450. X    if (Governor && Stars[snum]->governor[Playernum - 1] != Governor) {
  1451. X        notify(Playernum, Governor, "You are not authorized in this system.\n");
  1452. X        return;
  1453. X    }
  1454. X    Race = races[Playernum - 1];
  1455. X    if (Race->Guest) {
  1456. X        notify(Playernum, Governor, "Guest races can't sell anything.\n");
  1457. X        return;
  1458. X    }
  1459. X    /* get information on sale */
  1460. X    commod = args[1][0];
  1461. X    amount = atoi(args[2]);
  1462. X    if (amount <= 0) {
  1463. X        notify(Playernum, Governor, "Try using positive values.\n");
  1464. X        return;
  1465. X    }
  1466. X    APcount = MIN(APcount, amount);
  1467. X    if (!enufAP(Playernum, Governor, Stars[snum]->AP[Playernum - 1], APcount))
  1468. X        return;
  1469. X    getplanet(&p, snum, pnum);
  1470. X
  1471. X    if (p->slaved_to && p->slaved_to != Playernum) {
  1472. X        sprintf(buf, "This planet is enslaved to player %d.\n", p->slaved_to);
  1473. X        notify(Playernum, Governor, buf);
  1474. X        free(p);
  1475. X        return;
  1476. X    }
  1477. X    /* check to see if there is an undamage gov center or space port here */
  1478. X    sh = p->ships;
  1479. X    while (sh && !ok) {
  1480. X        (void) getship(&s, sh);
  1481. X        if (s->alive && (s->owner == Playernum) && !s->damage &&
  1482. X            Shipdata[s->type][ABIL_PORT])
  1483. X            ok = 1;
  1484. X        sh = s->nextship;
  1485. X        free(s);
  1486. X    }
  1487. X    if (!ok) {
  1488. X        notify(Playernum, Governor, "You don't have an undamaged space port or government center here.\n");
  1489. X        free(p);
  1490. X        return;
  1491. X    }
  1492. X    switch (commod) {
  1493. X    case 'r':
  1494. X        if (!p->info[Playernum - 1].resource) {
  1495. X            notify(Playernum, Governor, "You don't have any resources here to sell!\n");
  1496. X            free(p);
  1497. X            return;
  1498. X        }
  1499. X        amount = MIN(amount, p->info[Playernum - 1].resource);
  1500. X        p->info[Playernum - 1].resource -= amount;
  1501. X        item = RESOURCE;
  1502. X        break;
  1503. X    case 'd':
  1504. X        if (!p->info[Playernum - 1].destruct) {
  1505. X            notify(Playernum, Governor, "You don't have any destruct here to sell!\n");
  1506. X            free(p);
  1507. X            return;
  1508. X        }
  1509. X        amount = MIN(amount, p->info[Playernum - 1].destruct);
  1510. X        p->info[Playernum - 1].destruct -= amount;
  1511. X        item = DESTRUCT;
  1512. X        break;
  1513. X    case 'f':
  1514. X        if (!p->info[Playernum - 1].fuel) {
  1515. X            notify(Playernum, Governor, "You don't have any fuel here to sell!\n");
  1516. X            free(p);
  1517. X            return;
  1518. X        }
  1519. X        amount = MIN(amount, p->info[Playernum - 1].fuel);
  1520. X        p->info[Playernum - 1].fuel -= amount;
  1521. X        item = FUEL;
  1522. X        break;
  1523. X    case 'x':
  1524. X        if (!p->info[Playernum - 1].crystals) {
  1525. X            notify(Playernum, Governor, "You don't have any crystals here to sell!\n");
  1526. X            free(p);
  1527. X            return;
  1528. X        }
  1529. X        amount = MIN(amount, p->info[Playernum - 1].crystals);
  1530. X        p->info[Playernum - 1].crystals -= amount;
  1531. X        item = CRYSTAL;
  1532. X        break;
  1533. X    default:
  1534. X        notify(Playernum, Governor, "Permitted commodities are r, d, f, and x.\n");
  1535. X        free(p);
  1536. X        return;
  1537. X    }
  1538. X
  1539. X    c.owner = Playernum;
  1540. X    c.governor = Governor;
  1541. X    c.type = item;
  1542. X    c.amount = amount;
  1543. X    c.deliver = 0;
  1544. X    c.bid = 0;
  1545. X    c.bidder = 0;
  1546. X    c.star_from = snum;
  1547. X    c.planet_from = pnum;
  1548. X
  1549. X    while ((commodno = getdeadcommod()) == 0);
  1550. X
  1551. X    if (commodno == -1)
  1552. X        commodno = Numcommods() + 1;
  1553. X    sprintf(buf, "Lot #%d - %d units of %s.\n",
  1554. X        commodno, amount, Commod[item]);
  1555. X    notify(Playernum, Governor, buf);
  1556. X    sprintf(buf, "Lot #%d - %d units of %s for sale by %s [%d].\n",
  1557. X        commodno, amount, Commod[item], races[Playernum - 1]->name,
  1558. X        Playernum);
  1559. X    post(buf, TRANSFER);
  1560. X    for (i = 1; i <= Num_races; i++)
  1561. X        notify_race(i, buf);
  1562. X    putcommod(&c, commodno);
  1563. X    putplanet(p, snum, pnum);
  1564. X    free(p);
  1565. X    deductAPs(Playernum, Governor, APcount, snum, 0);
  1566. X}
  1567. X
  1568. Xvoid 
  1569. Xbid(int Playernum, int Governor, int APcount)
  1570. X{
  1571. X    racetype       *Race;
  1572. X    planettype     *p;
  1573. X    commodtype     *c;
  1574. X    commodtype     *cc;
  1575. X    shiptype       *s;
  1576. X    char            commod;
  1577. X    int             i, item, bid0, lot, shipping, ok = 0, sh;
  1578. X    int             u, shipcost = 0, money_owed = 0;
  1579. X    int             minbid;
  1580. X    double          dist, rate;
  1581. X    int             snum, pnum;
  1582. X
  1583. X    if (argn == 1) {
  1584. X        /* list all market blocks for sale */
  1585. X        notify(Playernum, Governor, "+++ Galactic Bloodshed Commodities Market +++\n\n");
  1586. X        notify(Playernum, Governor, "  Lot Stock      Type  Owner  Bidder  Amount Cost/Unit    Ship  Dest\n");
  1587. X        for (i = 1; i <= Numcommods(); i++) {
  1588. X            getcommod(&c, i);
  1589. X            if (c->owner && c->amount) {
  1590. X                rate = (double) c->bid / (double) c->amount;
  1591. X                if (c->bidder == Playernum)
  1592. X                    sprintf(temp, "%4.4s/%-4.4s", Stars[c->star_to]->name,
  1593. X                        Stars[c->star_to]->pnames[c->planet_to]);
  1594. X                else
  1595. X                    sprintf(temp, "");
  1596. X                sprintf(buf, " %4d%c%5d%10s%7d%8d%8d%10.2f%8d %10s\n",
  1597. X                    i, c->deliver ? '*' : ' ', c->amount,
  1598. X                    Commod[c->type], c->owner, c->bidder, c->bid, rate,
  1599. X                    shipping_cost((int) c->star_from,
  1600. X                    (int) Dir[Playernum - 1][Governor].snum,
  1601. X                        &dist, (int) c->bid), temp);
  1602. X                notify(Playernum, Governor, buf);
  1603. X            }
  1604. X            free(c);
  1605. X        }
  1606. X    } else if (argn == 2) {
  1607. X        /* list all market blocks for sale of the requested type */
  1608. X        commod = args[1][0];
  1609. X        switch (commod) {
  1610. X        case 'r':
  1611. X            item = RESOURCE;
  1612. X            break;
  1613. X        case 'd':
  1614. X            item = DESTRUCT;
  1615. X            break;
  1616. X        case 'f':
  1617. X            item = FUEL;
  1618. X            break;
  1619. X        case 'x':
  1620. X            item = CRYSTAL;
  1621. X            break;
  1622. X        default:
  1623. X            notify(Playernum, Governor, "No such type of commodity.\n");
  1624. X            return;
  1625. X        }
  1626. X        notify(Playernum, Governor, "+++ Galactic Bloodshed Commodities Market +++\n\n");
  1627. X        notify(Playernum, Governor, "  Lot Stock      Type  Owner  Bidder  Amount Cost/Unit    Ship  Dest\n");
  1628. X        for (i = 1; i <= Numcommods(); i++) {
  1629. X            getcommod(&c, i);
  1630. X            if (c->owner && c->amount && (c->type == item)) {
  1631. X                rate = (double) c->bid / (double) c->amount;
  1632. X                if (c->bidder == Playernum)
  1633. X                    sprintf(temp, "%4.4s/%-4.4s", Stars[c->star_to]->name,
  1634. X                        Stars[c->star_to]->pnames[c->planet_to]);
  1635. X                else
  1636. X                    sprintf(temp, "");
  1637. X                sprintf(buf, " %4d%c%5d%10s%7d%8d%8d%10.2f%8d %10s\n",
  1638. X                    i, c->deliver ? '*' : ' ', c->amount,
  1639. X                    Commod[c->type], c->owner, c->bidder, c->bid, rate,
  1640. X                    shipping_cost((int) c->star_from,
  1641. X                    (int) Dir[Playernum - 1][Governor].snum,
  1642. X                        &dist, (int) c->bid), temp);
  1643. X                notify(Playernum, Governor, buf);
  1644. X            }
  1645. X            free(c);
  1646. X        }
  1647. X    } else {
  1648. X        if (Dir[Playernum - 1][Governor].level != LEVEL_PLAN) {
  1649. X            notify(Playernum, Governor, "You have to be in a planet scope to buy.\n");
  1650. X            return;
  1651. X        }
  1652. X        snum = Dir[Playernum - 1][Governor].snum;
  1653. X        pnum = Dir[Playernum - 1][Governor].pnum;
  1654. X        if (Governor && Stars[snum]->governor[Playernum - 1] != Governor) {
  1655. X            notify(Playernum, Governor, "You are not authorized in this system.\n");
  1656. X            return;
  1657. X        }
  1658. X        getplanet(&p, snum, pnum);
  1659. X        /*
  1660. X         * Cant bid from an enslaved planet
  1661. X         */
  1662. X        if (p->slaved_to && p->slaved_to != Playernum) {
  1663. X            sprintf(buf, "This planet is enslaved to player %d.\n", p->slaved_to);
  1664. X            notify(Playernum, Governor, buf);
  1665. X            free(p);
  1666. X            return;
  1667. X        }
  1668. X        /*
  1669. X         * check to see if there is an undamaged gov center or space
  1670. X         * port here
  1671. X         */
  1672. X        sh = p->ships;
  1673. X        while (sh && !ok) {
  1674. X            (void) getship(&s, sh);
  1675. X            if (s->alive && (s->owner == Playernum) && !s->damage &&
  1676. X                Shipdata[s->type][ABIL_PORT])
  1677. X                ok = 1;
  1678. X            sh = s->nextship;
  1679. X            free(s);
  1680. X        }
  1681. X
  1682. X        if (!ok) {
  1683. X            notify(Playernum, Governor,
  1684. X                   "You don't have an undamaged space port or government center here.\n");
  1685. X            free(p);
  1686. X            return;
  1687. X        }
  1688. X        lot = atoi(args[1]);
  1689. X        bid0 = atoi(args[2]);
  1690. X
  1691. X        if ((lot <= 0) || lot > Numcommods()) {
  1692. X            notify(Playernum, Governor, "Illegal lot number.\n");
  1693. X            free(p);
  1694. X            return;
  1695. X        }
  1696. X        /*
  1697. X         * What the HELL does this do?!
  1698. X         */
  1699. X        getcommod(&c, lot);
  1700. X        if (!c->owner) {
  1701. X            notify(Playernum, Governor, "No such lot for sale.\n");
  1702. X            free(p);
  1703. X            free(c);
  1704. X            return;
  1705. X        }
  1706. X        /*
  1707. X         * if (c->owner == Playernum && (c->star_from !=
  1708. X         * Dir[Playernum-1][c->governor].snum || c->planet_from !=
  1709. X         * Dir[Playernum-1][c->governor].pnum)) { notify(Playernum,
  1710. X         * Governor, "You can only set a minimum price for your lot
  1711. X         * from the location it was sold.\n"); free(p); free(c);
  1712. X         * return; }
  1713. X         */
  1714. X        minbid = (int) ((double) c->bid * (1.0 + UP_BID));
  1715. X        if (bid0 <= minbid) {
  1716. X            sprintf(buf, "You have to bid more than %d.\n", minbid);
  1717. X            notify(Playernum, Governor, buf);
  1718. X            free(p);
  1719. X            free(c);
  1720. X            return;
  1721. X        }
  1722. X        /*
  1723. X         * Don't allow guests to screw things up
  1724. X         */
  1725. X        Race = races[Playernum - 1];
  1726. X        if (Race->Guest) {
  1727. X            notify(Playernum, Governor, "Guest races cannot bid.\n");
  1728. X            free(p);
  1729. X            free(c);
  1730. X            return;
  1731. X        }
  1732. X        /*
  1733. X         * Make sure they have the bucks
  1734. X         */
  1735. X        if (bid0 > Race->governor[Governor].money) {
  1736. X            notify(Playernum, Governor, "Sorry, no buying on credit allowed.\n");
  1737. X            free(p);
  1738. X            free(c);
  1739. X            return;
  1740. X        }
  1741. X        /*
  1742. X         * Make sure we check to see if we have enough for shipping
  1743. X         * costs as well.    --JPD--
  1744. X         */
  1745. X        shipcost = shipping_cost((int) c->star_to, (int) c->star_from,
  1746. X                     &dist, (int) c->bid);
  1747. X
  1748. X        if ((bid0 + shipcost) > Race->governor[Governor].money) {
  1749. X            sprintf(buf, "The bid (%d) + shipping costs (%d) exceed your money (%d)\n",
  1750. X                bid0, shipcost, Race->governor[Governor].money);
  1751. X            notify(Playernum, Governor, buf);
  1752. X            free(p);
  1753. X            free(c);
  1754. X            return;
  1755. X        }
  1756. X        /*
  1757. X         * Also make sure they have not bid on other things and used
  1758. X         * money earmarked for other lots --JPD--
  1759. X         */
  1760. X
  1761. X        for (u = 1; u <= Numcommods(); u++) {
  1762. X            getcommod(&cc, u);
  1763. X            if (cc->bidder == Playernum)
  1764. X                money_owed += cc->bid;
  1765. X        }
  1766. X        free(cc);
  1767. X
  1768. X        if (((bid0 + shipcost) + money_owed) > Race->governor[Governor].money) {
  1769. X            notify(Playernum, Governor, "All your money is used in bids already\n");
  1770. X            free(p);
  1771. X            free(c);
  1772. X            return;
  1773. X        }
  1774. X        /*
  1775. X         * They passed the credit check, notify the previous bidder
  1776. X         * that he was just outbidded
  1777. X         */
  1778. X        if (c->bidder) {
  1779. X            sprintf(buf, "The bid on lot #%d (%d %s) has been upped to %d by %s [%d].\n", lot, c->amount, Commod[c->type], bid0, Race->name, Playernum);
  1780. X            notify((int) c->bidder, (int) c->bidder_gov, buf);
  1781. X        }
  1782. X        /*
  1783. X         * Set the commod structs to the new values
  1784. X         */
  1785. X        c->bid = bid0;
  1786. X        c->bidder = Playernum;
  1787. X        c->bidder_gov = Governor;
  1788. X        c->star_to = snum;
  1789. X        c->planet_to = pnum;
  1790. X        shipping = shipcost;
  1791. X
  1792. X        sprintf(buf, "There will be an additional %d charged to you for shipping costs.\n", shipping);
  1793. X        notify(Playernum, Governor, buf);
  1794. X        putcommod(c, lot);
  1795. X        notify(Playernum, Governor, "Bid accepted.\n");
  1796. X        free(p);
  1797. X        free(c);
  1798. X    }
  1799. X}
  1800. X
  1801. Xint 
  1802. Xshipping_cost(int to, int from, double *dist, int value)
  1803. X{
  1804. X    double          factor, fcost;
  1805. X    int             junk;
  1806. X
  1807. X    *dist = sqrt(Distsq(Stars[to]->xpos, Stars[to]->ypos,
  1808. X                Stars[from]->xpos, Stars[from]->ypos));
  1809. X
  1810. X    junk = (int) (*dist / 10000.0);
  1811. X    junk *= 10000;
  1812. X
  1813. X    factor = 1.0 - exp(-(double) junk / MERCHANT_LENGTH);
  1814. X
  1815. X    fcost = factor * (double) value;
  1816. X    return (int) fcost;
  1817. X
  1818. X}
  1819. X#endif
  1820. END_OF_FILE
  1821. if test 51681 -ne `wc -c <'user/build.c2'`; then
  1822.     echo shar: \"'user/build.c2'\" unpacked with wrong size!
  1823. fi
  1824. # end of 'user/build.c2'
  1825. fi
  1826. echo shar: End of archive 2 \(of 21\).
  1827. cp /dev/null ark2isdone
  1828. MISSING=""
  1829. 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
  1830.     if test ! -f ark${I}isdone ; then
  1831.     MISSING="${MISSING} ${I}"
  1832.     fi
  1833. done
  1834. if test "${MISSING}" = "" ; then
  1835.     echo You have unpacked all 21 archives.
  1836.     echo "Now type './buildfiles.sh'"
  1837.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1838. else
  1839.     echo You still need to unpack the following archives:
  1840.     echo "        " ${MISSING}
  1841. fi
  1842. ##  End of shell archive.
  1843. exit 0
  1844.