computer.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /* $NetBSD: computer.c,v 1.10 2004/01/27 20:30:30 jsm Exp $ */
  2. /*
  3. * Copyright (c) 1980, 1993
  4. * The Regents of the University of California. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the University nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. */
  30. #include <sys/cdefs.h>
  31. #ifndef lint
  32. #if 0
  33. static char sccsid[] = "@(#)computer.c 8.1 (Berkeley) 5/31/93";
  34. #else
  35. __RCSID("$NetBSD: computer.c,v 1.10 2004/01/27 20:30:30 jsm Exp $");
  36. #endif
  37. #endif /* not lint */
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <math.h>
  41. #include "trek.h"
  42. #include "getpar.h"
  43. /*
  44. ** On-Board Computer
  45. **
  46. ** A computer request is fetched from the captain. The requests
  47. ** are:
  48. **
  49. ** chart -- print a star chart of the known galaxy. This includes
  50. ** every quadrant that has ever had a long range or
  51. ** a short range scan done of it, plus the location of
  52. ** all starbases. This is of course updated by any sub-
  53. ** space radio broadcasts (unless the radio is out).
  54. ** The format is the same as that of a long range scan
  55. ** except that ".1." indicates that a starbase exists
  56. ** but we know nothing else.
  57. **
  58. ** trajectory -- gives the course and distance to every know
  59. ** Klingon in the quadrant. Obviously this fails if the
  60. ** short range scanners are out.
  61. **
  62. ** course -- gives a course computation from whereever you are
  63. ** to any specified location. If the course begins
  64. ** with a slash, the current quadrant is taken.
  65. ** Otherwise the input is quadrant and sector coordi-
  66. ** nates of the target sector.
  67. **
  68. ** move -- identical to course, except that the move is performed.
  69. **
  70. ** score -- prints out the current score.
  71. **
  72. ** pheff -- "PHaser EFFectiveness" at a given distance. Tells
  73. ** you how much stuff you need to make it work.
  74. **
  75. ** warpcost -- Gives you the cost in time and units to move for
  76. ** a given distance under a given warp speed.
  77. **
  78. ** impcost -- Same for the impulse engines.
  79. **
  80. ** distresslist -- Gives a list of the currently known starsystems
  81. ** or starbases which are distressed, together with their
  82. ** quadrant coordinates.
  83. **
  84. ** If a command is terminated with a semicolon, you remain in
  85. ** the computer; otherwise, you escape immediately to the main
  86. ** command processor.
  87. */
  88. struct cvntab Cputab[] =
  89. {
  90. { "ch", "art", (cmdfun)1, 0 },
  91. { "t", "rajectory", (cmdfun)2, 0 },
  92. { "c", "ourse", (cmdfun)3, 0 },
  93. { "m", "ove", (cmdfun)3, 1 },
  94. { "s", "core", (cmdfun)4, 0 },
  95. { "p", "heff", (cmdfun)5, 0 },
  96. { "w", "arpcost", (cmdfun)6, 0 },
  97. { "i", "mpcost", (cmdfun)7, 0 },
  98. { "d", "istresslist", (cmdfun)8, 0 },
  99. { NULL, NULL, NULL, 0 }
  100. };
  101. static int kalc(int, int, int, int, double *);
  102. static void prkalc(int, double);
  103. /*ARGSUSED*/
  104. void
  105. computer(v)
  106. int v __attribute__((__unused__));
  107. {
  108. int ix, iy;
  109. int i, j;
  110. int tqx, tqy;
  111. const struct cvntab *r;
  112. int cost;
  113. int course;
  114. double dist, time;
  115. double warpfact;
  116. struct quad *q;
  117. struct event *e;
  118. if (check_out(COMPUTER))
  119. return;
  120. while (1)
  121. {
  122. r = getcodpar("\nRequest", Cputab);
  123. switch ((long)r->value)
  124. {
  125. case 1: /* star chart */
  126. printf("Computer record of galaxy for all long range sensor scans\n\n");
  127. printf(" ");
  128. /* print top header */
  129. for (i = 0; i < NQUADS; i++)
  130. printf("-%d- ", i);
  131. printf("\n");
  132. for (i = 0; i < NQUADS; i++)
  133. {
  134. printf("%d ", i);
  135. for (j = 0; j < NQUADS; j++)
  136. {
  137. if (i == Ship.quadx && j == Ship.quady)
  138. {
  139. printf("$$$ ");
  140. continue;
  141. }
  142. q = &Quad[i][j];
  143. /* 1000 or 1001 is special case */
  144. if (q->scanned >= 1000)
  145. if (q->scanned > 1000)
  146. printf(".1. ");
  147. else
  148. printf("/// ");
  149. else
  150. if (q->scanned < 0)
  151. printf("... ");
  152. else
  153. printf("%3d ", q->scanned);
  154. }
  155. printf("%d\n", i);
  156. }
  157. printf(" ");
  158. /* print bottom footer */
  159. for (i = 0; i < NQUADS; i++)
  160. printf("-%d- ", i);
  161. printf("\n");
  162. break;
  163. case 2: /* trajectory */
  164. if (check_out(SRSCAN))
  165. {
  166. break;
  167. }
  168. if (Etc.nkling <= 0)
  169. {
  170. printf("No Klingons in this quadrant\n");
  171. break;
  172. }
  173. /* for each Klingon, give the course & distance */
  174. for (i = 0; i < Etc.nkling; i++)
  175. {
  176. printf("Klingon at %d,%d", Etc.klingon[i].x, Etc.klingon[i].y);
  177. course = kalc(Ship.quadx, Ship.quady, Etc.klingon[i].x, Etc.klingon[i].y, &dist);
  178. prkalc(course, dist);
  179. }
  180. break;
  181. case 3: /* course calculation */
  182. if (readdelim('/'))
  183. {
  184. tqx = Ship.quadx;
  185. tqy = Ship.quady;
  186. }
  187. else
  188. {
  189. ix = getintpar("Quadrant");
  190. if (ix < 0 || ix >= NSECTS)
  191. break;
  192. iy = getintpar("q-y");
  193. if (iy < 0 || iy >= NSECTS)
  194. break;
  195. tqx = ix;
  196. tqy = iy;
  197. }
  198. ix = getintpar("Sector");
  199. if (ix < 0 || ix >= NSECTS)
  200. break;
  201. iy = getintpar("s-y");
  202. if (iy < 0 || iy >= NSECTS)
  203. break;
  204. course = kalc(tqx, tqy, ix, iy, &dist);
  205. if (r->value2)
  206. {
  207. warp(-1, course, dist);
  208. break;
  209. }
  210. printf("%d,%d/%d,%d to %d,%d/%d,%d",
  211. Ship.quadx, Ship.quady, Ship.sectx, Ship.secty, tqx, tqy, ix, iy);
  212. prkalc(course, dist);
  213. break;
  214. case 4: /* score */
  215. score();
  216. break;
  217. case 5: /* phaser effectiveness */
  218. dist = getfltpar("range");
  219. if (dist < 0.0)
  220. break;
  221. dist *= 10.0;
  222. cost = pow(0.90, dist) * 98.0 + 0.5;
  223. printf("Phasers are %d%% effective at that range\n", cost);
  224. break;
  225. case 6: /* warp cost (time/energy) */
  226. dist = getfltpar("distance");
  227. if (dist < 0.0)
  228. break;
  229. warpfact = getfltpar("warp factor");
  230. if (warpfact <= 0.0)
  231. warpfact = Ship.warp;
  232. cost = (dist + 0.05) * warpfact * warpfact * warpfact;
  233. time = Param.warptime * dist / (warpfact * warpfact);
  234. printf("Warp %.2f distance %.2f cost %.2f stardates %d (%d w/ shlds up) units\n",
  235. warpfact, dist, time, cost, cost + cost);
  236. break;
  237. case 7: /* impulse cost */
  238. dist = getfltpar("distance");
  239. if (dist < 0.0)
  240. break;
  241. cost = 20 + 100 * dist;
  242. time = dist / 0.095;
  243. printf("Distance %.2f cost %.2f stardates %d units\n",
  244. dist, time, cost);
  245. break;
  246. case 8: /* distresslist */
  247. j = 1;
  248. printf("\n");
  249. /* scan the event list */
  250. for (i = 0; i < MAXEVENTS; i++)
  251. {
  252. e = &Event[i];
  253. /* ignore hidden entries */
  254. if (e->evcode & E_HIDDEN)
  255. continue;
  256. switch (e->evcode & E_EVENT)
  257. {
  258. case E_KDESB:
  259. printf("Klingon is attacking starbase in quadrant %d,%d\n",
  260. e->x, e->y);
  261. j = 0;
  262. break;
  263. case E_ENSLV:
  264. case E_REPRO:
  265. printf("Starsystem %s in quadrant %d,%d is distressed\n",
  266. Systemname[e->systemname], e->x, e->y);
  267. j = 0;
  268. break;
  269. }
  270. }
  271. if (j)
  272. printf("No known distress calls are active\n");
  273. break;
  274. }
  275. /* skip to next semicolon or newline. Semicolon
  276. * means get new computer request; newline means
  277. * exit computer mode. */
  278. while ((i = cgetc(0)) != ';')
  279. {
  280. if (i == '\0')
  281. exit(1);
  282. if (i == '\n')
  283. {
  284. ungetc(i, stdin);
  285. return;
  286. }
  287. }
  288. }
  289. }
  290. /*
  291. ** Course Calculation
  292. **
  293. ** Computes and outputs the course and distance from position
  294. ** sqx,sqy/ssx,ssy to tqx,tqy/tsx,tsy.
  295. */
  296. static int
  297. kalc(tqx, tqy, tsx, tsy, dist)
  298. int tqx;
  299. int tqy;
  300. int tsx;
  301. int tsy;
  302. double *dist;
  303. {
  304. double dx, dy;
  305. double quadsize;
  306. double angle;
  307. int course;
  308. /* normalize to quadrant distances */
  309. quadsize = NSECTS;
  310. dx = (Ship.quadx + Ship.sectx / quadsize) - (tqx + tsx / quadsize);
  311. dy = (tqy + tsy / quadsize) - (Ship.quady + Ship.secty / quadsize);
  312. /* get the angle */
  313. angle = atan2(dy, dx);
  314. /* make it 0 -> 2 pi */
  315. if (angle < 0.0)
  316. angle += 6.283185307;
  317. /* convert from radians to degrees */
  318. course = angle * 57.29577951 + 0.5;
  319. dx = dx * dx + dy * dy;
  320. *dist = sqrt(dx);
  321. return (course);
  322. }
  323. static void
  324. prkalc(course, dist)
  325. int course;
  326. double dist;
  327. {
  328. printf(": course %d dist %.3f\n", course, dist);
  329. }