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