Fix the logic around remkl.
[super-star-trek.git] / finish.c
1 #include "sst.h"
2 #include <string.h>
3 #include <time.h>
4
5 void dstrct() 
6 {
7     /* Finish with a BANG! */
8     chew();
9     if (game.damage[DCOMPTR] != 0.0) {
10         prout("Computer damaged; cannot execute destruct sequence.");
11         return;
12     }
13     prouts("---WORKING---"); skip(1);
14     prouts("SELF-DESTRUCT-SEQUENCE-ACTIVATED"); skip(1);
15     prouts("   10"); skip(1);
16     prouts("       9"); skip(1);
17     prouts("          8"); skip(1);
18     prouts("             7"); skip(1);
19     prouts("                6"); skip(1);
20     skip(1);
21     prout("ENTER-CORRECT-PASSWORD-TO-CONTINUE-");
22     skip(1);
23     prout("SELF-DESTRUCT-SEQUENCE-OTHERWISE-");
24     skip(1);
25     prout("SELF-DESTRUCT-SEQUENCE-WILL-BE-ABORTED");
26     skip(1);
27     scan();
28     chew();
29     if (strcmp(game.passwd, citem) != 0) {
30         prouts("PASSWORD-REJECTED;"); skip(1);
31         prouts("CONTINUITY-EFFECTED");
32         skip(2);
33         return;
34     }
35     prouts("PASSWORD-ACCEPTED"); skip(1);
36     prouts("                   5"); skip(1);
37     prouts("                      4"); skip(1);
38     prouts("                         3"); skip(1);
39     prouts("                            2"); skip(1);
40     prouts("                              1"); skip(1);
41     if (Rand() < 0.15) {
42         prouts("GOODBYE-CRUEL-WORLD");
43         skip(1);
44     }
45     kaboom();
46 }
47
48 void kaboom(void) 
49 {
50     stars();
51     if (ship==IHE) prouts("***");
52     prouts("********* Entropy of ");
53     crmshp();
54     prouts(" maximized *********");
55     skip(1);
56     stars();
57     skip(1);
58     if (nenhere != 0) {
59         double whammo = 25.0 * energy;
60         int l=1;
61         while (l <= nenhere) {
62             if (game.kpower[l]*game.kdist[l] <= whammo) 
63                 deadkl(game.kx[l],game.ky[l], game.quad[game.kx[l]][game.ky[l]], game.kx[l], game.ky[l]);
64             l++;
65         }
66     }
67     finish(FDILITHIUM);
68 }
69                                 
70
71 void finish(FINTYPE ifin) 
72 {
73     int igotit = 0;
74     alldone = 1;
75     skip(3);
76     prout("It is stardate %.1f.", game.state.date);
77     skip(1);
78     switch (ifin) {
79     case FWON: // Game has been won
80         if (game.state.nromrem != 0)
81             prout("The remaining %d Romulans surrender to Starfleet Command.",
82                   game.state.nromrem);
83
84         prout("You have smashed the Klingon invasion fleet and saved");
85         prout("the Federation.");
86         gamewon=1;
87         if (alive) {
88             double badpt;
89             badpt = 5.0*game.state.starkl + casual + 10.0*game.state.nplankl +
90                 45.*nhelp+100.*game.state.basekl;
91             if (ship == IHF) badpt += 100.0;
92             else if (ship == 0) badpt += 200.0;
93             if (badpt < 100.0) badpt = 0.0;     // Close enough!
94             if (game.state.date-indate < 5.0 ||
95                 // killsPerDate >= RateMax
96                 KLINGKILLED/(game.state.date-indate) >=
97                 0.1*skill*(skill+1.0) + 0.1 + 0.008*badpt) {
98                 skip(1);
99                 prout("In fact, you have done so well that Starfleet Command");
100                 switch (skill) {
101                 case SKILL_NOVICE:
102                     prout("promotes you one step in rank from \"Novice\" to \"Fair\".");
103                     break;
104                 case SKILL_FAIR:
105                     prout("promotes you one step in rank from \"Fair\" to \"Good\".");
106                     break;
107                 case SKILL_GOOD:
108                     prout("promotes you one step in rank from \"Good\" to \"Expert\".");
109                     break;
110                 case SKILL_EXPERT:
111                     prout("promotes you to Commodore Emeritus.");
112                     skip(1);
113                     prout("Now that you think you're really good, try playing");
114                     prout("the \"Emeritus\" game. It will splatter your ego.");
115                     break;
116                 case SKILL_EMERITUS:
117                     skip(1);
118                     proutn("Computer-  ");
119                     prouts("ERROR-ERROR-ERROR-ERROR");
120                     skip(2);
121                     prouts("  YOUR-SKILL-HAS-EXCEEDED-THE-CAPACITY-OF-THIS-PROGRAM");
122                     skip(1);
123                     prouts("  THIS-PROGRAM-MUST-SURVIVE");
124                     skip(1);
125                     prouts("  THIS-PROGRAM-MUST-SURVIVE");
126                     skip(1);
127                     prouts("  THIS-PROGRAM-MUST-SURVIVE");
128                     skip(1);
129                     prouts("  THIS-PROGRAM-MUST?- MUST ? - SUR? ? -?  VI");
130                     skip(2);
131                     prout("Now you can retire and write your own Star Trek game!");
132                     skip(1);
133                     break;
134                 }
135                 if (skill >= SKILL_EXPERT) {
136                     if (thawed
137 #ifdef DEBUG
138                         && !idebug
139 #endif
140                         )
141                         prout("You cannot get a citation, so...");
142                     else {
143                         proutn("Do you want your Commodore Emeritus Citation printed? ");
144                         chew();
145                         if (ja()) {
146                             igotit = 1;
147                         }
148                     }
149                 }
150             }
151             // Only grant long life if alive (original didn't!)
152             skip(1);
153             prout("LIVE LONG AND PROSPER.");
154         }
155         score();
156         if (igotit != 0) plaque();
157         return;
158     case FDEPLETE: // Federation Resources Depleted
159         prout("Your time has run out and the Federation has been");
160         prout("conquered.  Your starship is now Klingon property,");
161         prout("and you are put on trial as a war criminal.  On the");
162         proutn("basis of your record, you are ");
163         if (KLINGREM*3.0 > INKLINGTOT) {
164             prout("aquitted.");
165             skip(1);
166             prout("LIVE LONG AND PROSPER.");
167         }
168         else {
169             prout("found guilty and");
170             prout("sentenced to death by slow torture.");
171             alive = 0;
172         }
173         score();
174         return;
175     case FLIFESUP:
176         prout("Your life support reserves have run out, and");
177         prout("you die of thirst, starvation, and asphyxiation.");
178         prout("Your starship is a derelict in space.");
179         break;
180     case FNRG:
181         prout("Your energy supply is exhausted.");
182         skip(1);
183         prout("Your starship is a derelict in space.");
184         break;
185     case FBATTLE:
186         proutn("The ");
187         crmshp();
188         prout("has been destroyed in battle.");
189         skip(1);
190         prout("Dulce et decorum est pro patria mori.");
191         break;
192     case FNEG3:
193         prout("You have made three attempts to cross the negative energy");
194         prout("barrier which surrounds the galaxy.");
195         skip(1);
196         prout("Your navigation is abominable.");
197         score();
198         return;
199     case FNOVA:
200         prout("Your starship has been destroyed by a nova.");
201         prout("That was a great shot.");
202         skip(1);
203         break;
204     case FSNOVAED:
205         proutn("The ");
206         crmshp();
207         prout(" has been fried by a supernova.");
208         prout("...Not even cinders remain...");
209         break;
210     case FABANDN:
211         prout("You have been captured by the Klingons. If you still");
212         prout("had a starbase to be returned to, you would have been");
213         prout("repatriated and given another chance. Since you have");
214         prout("no starbases, you will be mercilessly tortured to death.");
215         break;
216     case FDILITHIUM:
217         prout("Your starship is now an expanding cloud of subatomic particles");
218         break;
219     case FMATERIALIZE:
220         prout("Starbase was unable to re-materialize your starship.");
221         prout("Sic transit gloria muntdi");
222         break;
223     case FPHASER:
224         proutn("The ");
225         crmshp();
226         prout(" has been cremated by its own phasers.");
227         break;
228     case FLOST:
229         prout("You and your landing party have been");
230         prout("converted to energy, disipating through space.");
231         break;
232     case FMINING:
233         prout("You are left with your landing party on");
234         prout("a wild jungle planet inhabited by primitive cannibals.");
235         skip(1);
236         prout("They are very fond of \"Captain Kirk\" soup.");
237         skip(1);
238         proutn("Without your leadership, the ");
239         crmshp();
240         prout(" is destroyed.");
241         break;
242     case FDPLANET:
243         prout("You and your mining party perish.");
244         skip(1);
245         prout("That was a great shot.");
246         skip(1);
247         break;
248     case FSSC:
249         prout("The Galileo is instantly annihilated by the supernova.");
250         // no break;
251     case FPNOVA:
252         prout("You and your mining party are atomized.");
253         skip(1);
254         proutn("Mr. Spock takes command of the ");
255         crmshp();
256         prout(" and");
257         prout("joins the Romulans, reigning terror on the Federation.");
258         break;
259     case FSTRACTOR:
260         prout("The shuttle craft Galileo is also caught,");
261         prout("and breaks up under the strain.");
262         skip(1);
263         prout("Your debris is scattered for millions of miles.");
264         proutn("Without your leadership, the ");
265         crmshp();
266         prout(" is destroyed.");
267         break;
268     case FDRAY:
269         prout("The mutants attack and kill Spock.");
270         prout("Your ship is captured by Klingons, and");
271         prout("your crew is put on display in a Klingon zoo.");
272         break;
273     case FTRIBBLE:
274         prout("Tribbles consume all remaining water,");
275         prout("food, and oxygen on your ship.");
276         skip(1);
277         prout("You die of thirst, starvation, and asphyxiation.");
278         prout("Your starship is a derelict in space.");
279         break;
280     case FHOLE:
281         prout("Your ship is drawn to the center of the black hole.");
282         prout("You are crushed into extremely dense matter.");
283         break;
284     }
285     if (ship==IHF) ship= 0;
286     else if (ship == IHE) ship = IHF;
287     alive = 0;
288     if (KLINGREM != 0) {
289         double goodies = game.state.remres/inresor;
290         double baddies = (game.state.remkl + 2.0*game.state.remcom)/(inkling+2.0*incom);
291         if (goodies/baddies >= 1.0+0.5*Rand()) {
292             prout("As a result of your actions, a treaty with the Klingon");
293             prout("Empire has been signed. The terms of the treaty are");
294             if (goodies/baddies >= 3.0+Rand()) {
295                 prout("favorable to the Federation.");
296                 skip(1);
297                 prout("Congratulations!");
298             }
299             else
300                 prout("highly unfavorable to the Federation.");
301         }
302         else
303             prout("The Federation will be destroyed.");
304     }
305     else {
306         prout("Since you took the last Klingon with you, you are a");
307         prout("martyr and a hero. Someday maybe they'll erect a");
308         prout("statue in your memory. Rest in peace, and try not");
309         prout("to think about pigeons.");
310         gamewon = 1;
311     }
312     score();
313 }
314
315 void score(void) 
316 {
317     double timused = game.state.date - indate;
318     int ithperd, iwon, klship;
319
320     iskill = skill;
321     if ((timused == 0 || KLINGREM != 0) && timused < 5.0) timused = 5.0;
322     perdate = KLINGKILLED/timused;
323     ithperd = 500*perdate + 0.5;
324     iwon = 0;
325     if (gamewon) iwon = 100*skill;
326     if (ship == IHE) klship = 0;
327     else if (ship == IHF) klship = 1;
328     else klship = 2;
329     if (gamewon == 0) game.state.nromrem = 0; // None captured if no win
330     iscore = 10*NKILLK + 50*NKILLC + ithperd + iwon
331         - 100*game.state.basekl - 100*klship - 45*nhelp -5*game.state.starkl - casual
332         + 20*NKILLROM + 200*NKILLSC - 10*game.state.nplankl + game.state.nromrem;
333     if (alive == 0) iscore -= 200;
334     skip(2);
335     prout("Your score --");
336     if (NKILLROM)
337         prout("%6d Romulans destroyed                 %5d",
338               NKILLROM,20*NKILLROM);
339     if (game.state.nromrem)
340         prout("%6d Romulans captured                  %5d",
341               game.state.nromrem, game.state.nromrem);
342     if (NKILLK)
343         prout("%6d ordinary Klingons destroyed        %5d",
344               NKILLK, 10*NKILLK);
345     if (NKILLC)
346         prout("%6d Klingon commanders destroyed       %5d",
347               NKILLC, 50*NKILLC);
348     if (NKILLSC)
349         prout("%6d Super-Commander destroyed          %5d",
350               NKILLSC, 200*NKILLSC);
351     if (ithperd)
352         prout("%6.2f Klingons per stardate              %5d",
353               perdate, ithperd);
354     if (game.state.starkl)
355         prout("%6d stars destroyed by your action     %5d",
356               game.state.starkl, -5*game.state.starkl);
357     if (game.state.nplankl)
358         prout("%6d planets destroyed by your action   %5d",
359               game.state.nplankl, -10*game.state.nplankl);
360     if (game.state.basekl)
361         prout("%6d bases destroyed by your action     %5d",
362               game.state.basekl, -100*game.state.basekl);
363     if (nhelp)
364         prout("%6d calls for help from starbase       %5d",
365               nhelp, -45*nhelp);
366     if (casual)
367         prout("%6d casualties incurred                %5d",
368               casual, -casual);
369     if (klship)
370         prout("%6d ship(s) lost or destroyed          %5d",
371               klship, -100*klship);
372     if (alive==0)
373         prout("Penalty for getting yourself killed        -200");
374     if (gamewon) {
375         proutn("Bonus for winning ");
376         switch (skill) {
377         case SKILL_NOVICE:   proutn("Novice game  "); break;
378         case SKILL_FAIR:     proutn("Fair game    "); break;
379         case SKILL_GOOD:     proutn("Good game    "); break;
380         case SKILL_EXPERT:   proutn("Expert game  "); break;
381         case SKILL_EMERITUS: proutn("Emeritus game"); break;
382         }
383         prout("           %5d", iwon);
384     }
385     skip(1);
386     prout("TOTAL SCORE                               %5d", iscore);
387 }
388
389 void plaque(void) {
390         FILE *fp=NULL;
391         time_t t;
392         char *timestring;
393         int nskip;
394         char winner[128];
395
396         skip(2);
397         
398         while (fp == NULL) {
399                 proutn("File or device name for your plaque: ");
400                 cgetline(winner, sizeof(winner));
401                 fp = fopen(winner, "w");
402                 if (fp==NULL) {
403                         prout("Invalid name.");
404                 }
405         }
406
407         proutn("Enter name to go on plaque (up to 30 characters): ");
408         cgetline(winner, sizeof(winner));
409         /* The 38 below must be 64 for 132-column paper */
410         nskip = 38 - strlen(winner)/2;
411
412         fprintf(fp,"\n\n\n\n");
413         /* --------DRAW ENTERPRISE PICTURE. */
414         fprintf(fp, "                                       EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n" );
415         fprintf(fp, "                                      EEE                      E  : :                                         :  E\n" );
416         fprintf(fp, "                                    EE   EEE                   E  : :                   NCC-1701              :  E\n");
417         fprintf(fp, "EEEEEEEEEEEEEEEE        EEEEEEEEEEEEEEE  : :                              : E\n");
418         fprintf(fp, " E                                     EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n");
419         fprintf(fp, "                      EEEEEEEEE               EEEEEEEEEEEEE                 E  E\n");
420         fprintf(fp, "                               EEEEEEE   EEEEE    E          E              E  E\n");
421         fprintf(fp, "                                      EEE           E          E            E  E\n");
422         fprintf(fp, "                                                       E         E          E  E\n");
423         fprintf(fp, "                                                         EEEEEEEEEEEEE      E  E\n");
424         fprintf(fp, "                                                      EEE :           EEEEEEE  EEEEEEEE\n");
425         fprintf(fp, "                                                    :E    :                 EEEE       E\n");
426         fprintf(fp, "                                                   .-E   -:-----                       E\n");
427         fprintf(fp, "                                                    :E    :                            E\n");
428         fprintf(fp, "                                                      EE  :                    EEEEEEEE\n");
429         fprintf(fp, "                                                       EEEEEEEEEEEEEEEEEEEEEEE\n");
430         fprintf(fp, "\n\n\n");
431         fprintf(fp, "                                                       U. S. S. ENTERPRISE\n");
432         fprintf(fp, "\n\n\n\n");
433         fprintf(fp, "                                  For demonstrating outstanding ability as a starship captain\n");
434         fprintf(fp, "\n");
435         fprintf(fp, "                                                Starfleet Command bestows to you\n");
436         fprintf(fp, "\n");
437         fprintf(fp,"%*s%s\n\n", nskip, "", winner);
438         fprintf(fp, "                                                           the rank of\n\n");
439         fprintf(fp, "                                                       \"Commodore Emeritus\"\n\n");
440         fprintf(fp, "                                                          ");
441         switch (iskill) {
442                 case SKILL_EXPERT: fprintf(fp," Expert level\n\n"); break;
443                 case SKILL_EMERITUS: fprintf(fp,"Emeritus level\n\n"); break;
444                 default: fprintf(fp," Cheat level\n\n"); break;
445         }
446         t = time(NULL);
447         timestring = ctime(&t);
448         fprintf(fp, "                                                 This day of %.6s %.4s, %.8s\n\n",
449                         timestring+4, timestring+20, timestring+11);
450         fprintf(fp,"                                                        Your score:  %d\n\n", iscore);
451         fprintf(fp,"                                                    Klingons per stardate:  %.2f\n", perdate);
452         fclose(fp);
453 }