1 /*
2  * File for the fun ends
3  * Death or a total win
4  *
5  * rip.c	1.4 (A.I. Design)	12/14/84
6  */
7 
8 #include "rogue.h"
9 #include "curses.h"
10 
11 static int sc_fd;
12 /*
13  * external curses IBM (jll)
14  */
15 extern int scr_type;
16 
17 /*
18  * score:
19  *	Figure score and post it.
20  */
21 /* VARARGS2 */
22 
23 
24 score(amount, flags, monst)
25 int amount, flags;
26 char monst;
27 {
28 #ifndef DEMO
29 #ifndef WIZARD
30     struct sc_ent his_score, top_ten[TOPSCORES];
31     register int newfile = FALSE, rank=0;
32     char response = ' ';
33 
34 
35     is_saved = TRUE;
36 
37     if (amount || flags || monst)
38     {
39 	move(LINES-1,0);
40         cursor(TRUE);
41 
42        printw("[Press Enter to see rankings]");
43        flush_type();
44        wait_for('\r');
45     	
46        move(LINES-1,0);
47     }
48     while ((sc_fd = open(s_score, 0)) < 0)
49     {
50         printw("\n");
51         if (noscore || (amount == 0))
52             return;
53         str_attr("No scorefile: %Create %Retry %Abort");
54         reread:
55         switch(response = readchar())
56         {
57      	    case 'c':
58     	    case 'C':
59 				close(creat(s_score, 0666));
60 	    case 'r':
61 	    case 'R':
62 		break;
63 	    case 'a':
64 	    case 'A':
65 		return;
66 	    default:
67 		goto reread;
68 	}
69     }
70     printw("\n");
71     get_scores(&top_ten);
72 
73     if (noscore != TRUE) 
74     {
75 	strcpy(his_score.sc_name,whoami);
76 	his_score.sc_gold = amount;
77 	his_score.sc_fate = flags ? flags : monst;
78 	his_score.sc_level = max_level;
79 	his_score.sc_rank  = pstats.s_lvl;
80 	rank = add_scores(&his_score,&top_ten);
81     }
82 	close(sc_fd);
83     if (rank > 0) {
84     	if ((sc_fd = creat(s_score, 0666)) >= 0) {
85     	    put_scores(&top_ten);
86 			close(sc_fd);
87 		}
88     }
89     pr_scores(rank,&top_ten);
90 #endif WIZARD
91 #endif DEMO
92 }
93 
94 #ifndef DEMO
95 #ifndef WIZARD
96 get_scores(top10)
97 	struct sc_ent *top10;
98 {
99 	register int i, retcode = 1;
100 
101 	for(i=0; i<TOPSCORES; i++,top10++) {
102 		if (retcode > 0)
103 			retcode = read(sc_fd,top10,sizeof(struct sc_ent));
104 		if (retcode <= 0)
105 			top10->sc_gold = 0;
106 	}
107 }
108 
109 
110 put_scores(top10)
111 	struct sc_ent *top10;
112 {
113     register int i;
114     
115     for (i=0;(i<TOPSCORES) && top10->sc_gold;i++,top10++) 
116     {
117 	if (write(sc_fd,top10,sizeof(struct sc_ent)) <= 0)
118             return;
119     }
120 }
121 
122 pr_scores(newrank,top10)
123 	int newrank;
124 	struct sc_ent *top10;
125 {
126     register int i;
127     register char *ki;
128     int curl;
129     char dthstr[30];
130     char *altmsg;
131 
132 	switch_page(old_page_no);
133 	clear();
134     high();
135     if (scr_type == 7)
136         standout();
137     mvaddstr(0,0,"Guildmaster's Hall Of Fame:");
138     standend();
139 	yellow();
140     mvaddstr(2,0,"Gold");
141 
142     for (i=0;i<TOPSCORES;i++,top10++)
143     {
144 		altmsg = NULL;
145     	brown();
146     	if (newrank - 1 == i)
147     	{
148     	    if (scr_type == 7)
149     	    	standout();
150     	    else
151     	        yellow();
152     	}
153 	if (top10->sc_gold <=0 )
154 		break;
155 	curl = 4 + ((COLS==40)?(i * 2):i);
156 	move (curl,0);
157 	printw("%d ",top10->sc_gold);
158 	move (curl,6);
159 	if (newrank - 1 != i)
160 		red();
161 	printw("%s",top10->sc_name);
162 	if ((newrank) - 1 != i)
163 	    brown();
164         if (top10->sc_level >= 26)
165             altmsg = " Honored by the Guild";
166 	if (isalpha(top10->sc_fate))
167         {
168             sprintf(dthstr," killed by %s",
169             		killname((0xff & top10->sc_fate), TRUE));
170             if (COLS == 40 && strlen(dthstr) > 23)
171             	strcpy(dthstr," killed");
172         }
173 	else
174 	    switch(top10->sc_fate) {
175 		    case 2:
176 	   	        altmsg = " A total winner!";
177 	    	        break;
178 	            case 1:
179 	                strcpy(dthstr," quit");
180 	                break;
181 	            default:
182 	                strcpy(dthstr," wierded out");
183 	    }
184 	if ((strlen(top10->sc_name) + 10 + 
185 		strlen(he_man[top10->sc_rank-1])) < COLS)
186 	{
187 	    if (top10->sc_rank > 1 && (strlen(top10->sc_name)))
188 	        printw(" \"%s\"",he_man[top10->sc_rank - 1]);
189 	}
190 	if (COLS == 40)
191         move(curl+1,6);
192         if (altmsg == NULL)
193             printw("%s on level %d",dthstr,top10->sc_level);
194         else
195             addstr(altmsg);
196     }
197     standend();
198     if (COLS == 80)
199     	addstr("\n\n\n\n");
200 }
201 
202 add_scores(newscore,oldlist)
203 	struct sc_ent *newscore, *oldlist;
204 {
205     register struct sc_ent *sentry, *insert;
206     int retcode = TOPSCORES+1;
207 
208     for(sentry=&oldlist[TOPSCORES-1];sentry>=oldlist;sentry--) {
209 	if ((unsigned)newscore->sc_gold > (unsigned)sentry->sc_gold) {
210 	    insert = sentry;
211 	    retcode--;
212 	    if ((insert < &oldlist[TOPSCORES-1]) && sentry->sc_gold)
213 			sentry[1] = *sentry;
214 	} else
215 	    break;
216    }
217    if (retcode == 11) 
218    	return 0;
219    *insert = *newscore;
220    return retcode;
221 }
222 #endif WIZARD
223 #endif DEMO
224 
225 /*
226  * death:
227  *	Do something really fun when he dies
228  */
229 death(monst)
230 register char monst;
231 {
232     register char *killer;
233     char buf[MAXSTR];
234     register int year;
235 #ifndef DEMO
236 
237     purse -= purse / 10;
238 
239     switch_page(old_page_no);
240     clear();
241     drop_curtain();
242     if (is_color)
243     	brown();
244     box((COLS==40)?1:7,(COLS-28)/2,22,(COLS+28)/2);
245     standend();
246 
247     center(10, "REST");
248     center(11, "IN");
249     center(12, "PEACE");
250     red();
251     center(21, "  *    *      * ");
252     green();
253     center(22, "___\\/(\\/)/(\\/ \\\\(//)\\)\\/(//)\\\\)//(\\__");
254     standend();
255 
256     if (scr_type == 7)
257         uline();
258     center(14, your_na);
259     standend();
260 
261     killer = killname(monst, TRUE);
262 
263     strcpy(buf,"killed by");
264 
265     center(15,buf);
266     center(16, kild_by);
267 
268     sprintf(buf, "%u Au", purse);
269     center(18, buf);
270 
271 	regs->ax = 0x2a << 8;
272 	swint(SW_DOS,regs);
273 	year = regs->cx;
274     sprintf(buf, "%u", year);
275     center(19, buf);
276 	raise_curtain();
277     move(LINES-1, 0);
278     score(purse, 0, monst);
279 #else DEMO
280     demo(0);
281     killer = killname(monst, TRUE);
282 
283     strcpy(buf,"This time you were killed by");
284     strcat(buf," ");
285     strcat(buf,killer);
286     if (strlen(buf) > (COLS-2))
287     	center(6,"This time you were killed");
288     else
289         center(6, buf);
290 	move(LINES-2,0);
291 #endif DEMO
292     wclose(0);
293     exit();
294 }
295 
296 /*
297  * total_winner:
298  *	Code for a winner
299  */
300 total_winner()
301 {
302 #ifndef DEMO
303     register THING *obj;
304     register int worth;
305     register byte c;
306     register int oldpurse;
307 
308 	switch_page(old_page_no);
309     clear();
310 #ifdef MINROG
311     if (!terse)
312     {
313     standout();
314     printw("                                                               \n");
315     printw("  @   @               @   @           @          @@@  @     @  \n");
316     printw("  @   @               @@ @@           @           @   @     @  \n");
317     printw("  @   @  @@@  @   @   @ @ @  @@@   @@@@  @@@      @  @@@    @  \n");
318     printw("   @@@@ @   @ @   @   @   @     @ @   @ @   @     @   @     @  \n");
319     printw("      @ @   @ @   @   @   @  @@@@ @   @ @@@@@     @   @     @  \n");
320     printw("  @   @ @   @ @  @@   @   @ @   @ @   @ @         @   @  @     \n");
321     printw("   @@@   @@@   @@ @   @   @  @@@@  @@@@  @@@     @@@   @@   @  \n");
322     }
323     printw("                                                               \n");
324     printw("     Congratulations, you have made it to the light of day!    \n");
325     standend();
326     printw("\nYou have joined the elite ranks of those who have escaped the\n");
327     printw("Dungeons of Doom alive.  You journey home and sell all your loot at\n");
328     printw("a great profit and are admitted to the fighters guild.\n");
329 #else
330     printw("Congratulations!\n\nYou have made it to the light of day!\n\n\n\n");
331     printw("You journey home and sell all your\n");
332     printw("loot at a great profit and are\n");
333     printw("admitted to the fighters guild.\n\n\n");
334 #endif MINROG
335     mvaddstr(LINES - 1, 0, "--Press space to continue--");
336     wait_for(' ');
337     clear();
338     mvaddstr(0, 0, "   Worth  Item");
339     oldpurse = purse;
340     for (c = 'a', obj = pack; obj != NULL; c++, obj = next(obj))
341     {
342 	switch (obj->o_type)
343 	{
344 	    when FOOD:
345 		worth = 2 * obj->o_count;
346 	    when WEAPON:
347 		switch (obj->o_which)
348 		{
349 		    when MACE: worth = 8;
350 		    when SWORD: worth = 15;
351 		    when CROSSBOW: worth = 30;
352 		    when ARROW: worth = 1;
353 		    when DAGGER: worth = 2;
354 		    when TWOSWORD: worth = 75;
355 		    when DART: worth = 1;
356 		    when BOW: worth = 15;
357 		    when BOLT: worth = 1;
358 		    when SPEAR: worth = 5;
359 		}
360 		worth *= 3 * (obj->o_hplus + obj->o_dplus) + obj->o_count;
361 		obj->o_flags |= ISKNOW;
362 	    when ARMOR:
363 		switch (obj->o_which)
364 		{
365 		    when LEATHER: worth = 20;
366 		    when RING_MAIL: worth = 25;
367 		    when STUDDED_LEATHER: worth = 20;
368 		    when SCALE_MAIL: worth = 30;
369 		    when CHAIN_MAIL: worth = 75;
370 		    when SPLINT_MAIL: worth = 80;
371 		    when BANDED_MAIL: worth = 90;
372 		    when PLATE_MAIL: worth = 150;
373 		}
374 		worth += (9 - obj->o_ac) * 100;
375 		worth += (10 * (a_class[obj->o_which] - obj->o_ac));
376 		obj->o_flags |= ISKNOW;
377 	    when SCROLL:
378 		worth = s_magic[obj->o_which].mi_worth;
379 		worth *= obj->o_count;
380 		if (!s_know[obj->o_which])
381 		    worth /= 2;
382 		s_know[obj->o_which] = TRUE;
383 	    when POTION:
384 		worth = p_magic[obj->o_which].mi_worth;
385 		worth *= obj->o_count;
386 		if (!p_know[obj->o_which])
387 		    worth /= 2;
388 		p_know[obj->o_which] = TRUE;
389 	    when RING:
390 		worth = r_magic[obj->o_which].mi_worth;
391 		if (obj->o_which == R_ADDSTR || obj->o_which == R_ADDDAM ||
392 		    obj->o_which == R_PROTECT || obj->o_which == R_ADDHIT)
393 			if (obj->o_ac > 0)
394 			    worth += obj->o_ac * 100;
395 			else
396 			    worth = 10;
397 		if (!(obj->o_flags & ISKNOW))
398 		    worth /= 2;
399 		obj->o_flags |= ISKNOW;
400 		r_know[obj->o_which] = TRUE;
401 	    when STICK:
402 		worth = ws_magic[obj->o_which].mi_worth;
403 		worth += 20 * obj->o_charges;
404 		if (!(obj->o_flags & ISKNOW))
405 		    worth /= 2;
406 		obj->o_flags |= ISKNOW;
407 		ws_know[obj->o_which] = TRUE;
408 	    when AMULET:
409 		worth = 1000;
410 	}
411 	if (worth < 0)
412 	    worth = 0;
413 	move(c - 'a' + 1, 0);
414 	printw( "%c) %5d  %s", c, worth, inv_name(obj, FALSE));
415 	purse += worth;
416     }
417     move(c - 'a' + 1, 0);
418     printw("   %5u  Gold Pieces          ", oldpurse);
419     score(purse, 2);
420 #endif DEMO
421     exit(0);
422 }
423 
424 /*
425  * killname:
426  *	Convert a code to a monster name
427  */
428 char *
429 killname(monst, doart)
430 register char monst;
431 bool doart;
432 {
433     register char *sp;
434     register bool article;
435 
436     sp = prbuf;
437     article = TRUE;
438     switch (monst)
439     {
440 	when 'a':
441 	    sp = "arrow";
442 	when 'b':
443 	    sp = "bolt";
444 	when 'd':
445 	    sp = "dart";
446 	when 's':
447 	    sp = "starvation";
448 	    article = FALSE;
449 	when 'f':
450 		sp = "fall";
451 	otherwise:
452 	    if (monst >= 'A' && monst <= 'Z')
453 		sp = monsters[monst-'A'].m_name;
454 	    else
455 	    {
456 		sp = "God";
457 		article = FALSE;
458 	    }
459     }
460     if (doart && article)
461 	sprintf(prbuf, "a%s ", vowelstr(sp));
462     else
463 	prbuf[0] = '\0';
464     strcat(prbuf, sp);
465     return prbuf;
466 }
467 
468 #ifdef DEMO
469 /*
470  * For the demonstration version of rogue we really want to
471  * Print out a message when the game ends telling them how
472  * order the game.
473  */
474 demo(endtype)
475 	int endtype;
476 {
477 	register int i;
478 	char demobuf[81];
479 
480 	switch_page(old_page_no);
481 	clear();
482 	if (is_color)
483 	    brown();
484 	box(0,0,LINES-2,COLS-1);
485 	bold();
486 	center(2,"ROGUE:  The Adventure Game");
487 	standend();
488 	if (is_color)
489 		lmagenta();
490 	sprintf(demobuf,"Sorry, %s but this is just a demonstration",whoami);
491 	if (terse)
492 		sprintf(demobuf,"Sorry, this is just a demonstration");
493 	center(4,demobuf);
494 	if (endtype == 1)   /* quiter */
495 	{
496 		sprintf(demobuf,"You quit with %u pieces of Gold",purse);
497 		center(6,demobuf);
498 	} else if (endtype == DEMOTIME) {
499 	    sprintf(demobuf,"You ended with %u gold pieces",purse);
500 		center(6,demobuf);
501     }
502 	if (terse)
503         	center(8,"If you're interested in doing some");
504         else
505 	        center(8,"But, if you're interested in doing some");
506 	center(9,"more exploring in the Dungeons of Doom");
507 	if (is_color)
508 	    red();
509 	center(11,"Please Contact:                      ");
510 	if (!is_color)
511 		uline();
512 	else
513 		standend();
514 	center(13,"A. I. Design");
515 	center(14,"P.O. Box  3685");
516 	center(15,"Santa Clara, California 95055");
517 	if (is_color)
518 		red();
519 	center(17,"(408) 296-1634");
520 	if (is_color)
521 	    yellow();
522 	else
523 	    standend();
524 	center(19,"(C) Copyright 1983");
525 	high();
526 	center(20,"Artificial Intelligence Design");
527 	if (is_color)
528 	    yellow();
529 	else
530 	    standend();
531 	center(21,"All Rights Reserved");
532 	if (endtype == 0)
533 		return;
534 	move(LINES-2,0);
535 	wclose(0);
536 	exit(0);
537 }
538 #endif DEMO
539 