diff rogue4/rip.c @ 12:9535a08ddc39

Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
author edwarj4
date Sat, 24 Oct 2009 16:52:52 +0000
parents
children 4967c46f1320
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue4/rip.c	Sat Oct 24 16:52:52 2009 +0000
@@ -0,0 +1,433 @@
+/*
+ * File for the fun ends
+ * Death or a total win
+ *
+ * @(#)rip.c	4.28 (Berkeley) 4/12/82
+ *
+ * Rogue: Exploring the Dungeons of Doom
+ * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include <curses.h>
+#include <time.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include "rogue.h"
+
+static char *rip[] = {
+"                       __________",
+"                      /          \\",
+"                     /    REST    \\",
+"                    /      IN      \\",
+"                   /     PEACE      \\",
+"                  /                  \\",
+"                  |                  |",
+"                  |                  |",
+"                  |   killed by a    |",
+"                  |                  |",
+"                  |       1980       |",
+"                 *|     *  *  *      | *",
+"         ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______",
+    0
+};
+
+/*
+ * score:
+ *	Figure score and post it.
+ */
+/* VARARGS2 */
+score(amount, flags, monst)
+int amount, flags;
+char monst;
+{
+    register struct sc_ent *scp;
+    register int i;
+    register struct sc_ent *sc2;
+    register FILE *outf;
+    register int prflags = 0;
+    register void (*fp)(int);
+    register int uid;
+    char scoreline[MAXSTR + 100];
+
+    static struct sc_ent {
+	char sc_name[MAXSTR];
+	unsigned int sc_flags;
+	unsigned int sc_uid;
+	unsigned short sc_monster;
+	unsigned short sc_score;
+	unsigned short sc_level;
+    } top_ten[10];
+    static char *reason[] = {
+	"killed",
+	"quit",
+	"A total winner",
+    };
+    void endit();
+
+    start_score();
+
+    if (fd >= 0)
+	outf = md_fdopen(fd, "wb");
+    else
+	return;
+
+    for (scp = top_ten; scp <= &top_ten[9]; scp++)
+    {
+	scp->sc_score = 0;
+	for (i = 0; i < MAXSTR; i++)
+	    scp->sc_name[i] = rnd(255);
+	scp->sc_flags = RN;
+	scp->sc_level = RN;
+	scp->sc_monster = RN;
+	scp->sc_uid = RN;
+    }
+
+    signal(SIGINT, SIG_DFL);
+    if (flags != -1
+#ifdef WIZARD
+	    || wizard
+#endif
+	)
+    {
+	mvaddstr(LINES - 1, 0 , "[Press return to continue]");
+        refresh();
+        wgetnstr(stdscr,prbuf,80);
+        move(LINES - 1, 0);
+        clrtoeol();
+        refresh();
+        endwin();
+    }
+#ifdef WIZARD
+    if (wizard)
+	if (strcmp(prbuf, "names") == 0)
+	    prflags = 1;
+	else if (strcmp(prbuf, "edit") == 0)
+	    prflags = 2;
+#endif
+    for(i=0; i<10; i++)
+    {
+        encread((char *) &top_ten[i].sc_name, MAXSTR, fd);
+	scoreline[0] = '\0';
+        encread((char *) scoreline, 100, fd);
+        sscanf(scoreline, "%d %d %hd %hd %hd", &top_ten[i].sc_flags, 
+            &top_ten[i].sc_uid, &top_ten[i].sc_monster, &top_ten[i].sc_score,
+            &top_ten[i].sc_level);
+    }
+    /*
+     * Insert her in list if need be
+     */
+    sc2 = NULL;
+    if (!noscore)
+    {
+	uid = md_getuid();
+
+	for (scp = top_ten; scp <= &top_ten[9]; scp++)
+	    if (amount > scp->sc_score)
+		break;
+#ifdef LIMIT_TOPTEN
+            else if (flags != 2 && scp->sc_uid == uid && scp->sc_flags != 2)
+		scp = &top_ten[9] + 1;	/* only one score per nowin uid */
+#endif
+	if (scp <= &top_ten[9])
+	{
+#ifdef LIMIT_TOPTEN
+	    if (flags != 2)
+		for (sc2 = scp; sc2 <= &top_ten[9]; sc2++)
+		{
+		    if (sc2->sc_uid == uid && sc2->sc_flags != 2)
+			break;
+		}
+	    else
+#endif
+		sc2 = &top_ten[9];
+	    while (sc2 > scp)
+	    {
+		*sc2 = sc2[-1];
+		sc2--;
+	    }
+	    scp->sc_score = amount;
+	    strncpy(scp->sc_name, whoami, MAXSTR);
+	    scp->sc_flags = flags;
+	    if (flags == 2)
+		scp->sc_level = max_level;
+	    else
+		scp->sc_level = level;
+	    scp->sc_monster = monst;
+	    scp->sc_uid = uid;
+	    sc2 = scp;
+	}
+    }
+    /*
+     * Print the list
+     */
+    printf("Top Ten Rogueists:\nRank\tScore\tName\n");
+    for (scp = top_ten; scp <= &top_ten[9]; scp++)
+    {
+	if (scp->sc_score) {
+	    printf("%d\t%d\t%s: %s on level %d", scp - top_ten + 1,
+		scp->sc_score, scp->sc_name, reason[scp->sc_flags],
+		scp->sc_level);
+	    if (scp->sc_flags == 0)
+		printf(" by %s", killname((char) scp->sc_monster, TRUE));
+	    if (prflags == 1)
+	    {
+		char *name;
+		name = md_getusername(scp->sc_uid);
+		   
+		if (name == NULL)
+		    printf(" (%d)", scp->sc_uid);
+		else
+		    printf(" (%s)", name);
+		putchar('\n');
+	    }
+	    else if (prflags == 2)
+	    {
+		fflush(stdout);
+          	fgets(prbuf,80,stdin);
+		if (prbuf[0] == 'd')
+		{
+		    for (sc2 = scp; sc2 < &top_ten[9]; sc2++)
+			*sc2 = *(sc2 + 1);
+		    top_ten[9].sc_score = 0;
+		    for (i = 0; i < MAXSTR; i++)
+			top_ten[9].sc_name[i] = rnd(255);
+		    top_ten[9].sc_flags = RN;
+		    top_ten[9].sc_level = RN;
+		    top_ten[9].sc_monster = RN;
+		    scp--;
+		}
+	    }
+	    else
+		printf(".\n");
+	}
+	else
+	    break;
+    }
+    fseek(outf, 0L, 0);
+    /*
+     * Update the list file
+     */
+    if (sc2 != NULL)
+    {
+	if (lock_sc())
+	{
+            int i;
+
+	    fp = signal(SIGINT, SIG_IGN);
+
+            for(i=0; i<10; i++)
+            {
+                encwrite((char *) &top_ten[i].sc_name, MAXSTR, outf);
+                sprintf(scoreline," %d %d %hd %hd %hd \n",
+                    top_ten[i].sc_flags, top_ten[i].sc_uid, 
+                    top_ten[i].sc_monster, top_ten[i].sc_score,
+                    top_ten[i].sc_level);
+                encwrite((char *) scoreline, 100, outf);
+            }
+	    unlock_sc();
+	    signal(SIGINT, fp);
+	}
+    }
+    fclose(outf);
+}
+
+/*
+ * death:
+ *	Do something really fun when he dies
+ */
+death(monst)
+register char monst;
+{
+    register char **dp = rip, *killer;
+    register struct tm *lt;
+    time_t date;
+    char buf[MAXSTR];
+    struct tm *localtime();
+
+    signal(SIGINT, SIG_IGN);
+    purse -= purse / 10;
+    signal(SIGINT, leave);
+    time(&date);
+    lt = localtime(&date);
+    clear();
+    move(8, 0);
+    while (*dp)
+	printw("%s\n", *dp++);
+    mvaddstr(14, 28-((strlen(whoami)+1)/2), whoami);
+    sprintf(buf, "%d Au", purse);
+    mvaddstr(15, 28-((strlen(buf)+1)/2), buf);
+    killer = killname(monst, FALSE);
+    mvaddstr(17, 28-((strlen(killer)+1)/2), killer);
+    if (monst == 's')
+	mvaddch(16, 32, ' ');
+    else
+	mvaddstr(16, 33, vowelstr(killer));
+    sprintf(prbuf, "%2d", 1900+lt->tm_year);
+    mvaddstr(18, 26, prbuf);
+    move(LINES-1, 0);
+    refresh();
+    score(purse, 0, monst);
+    exit(0);
+}
+
+/*
+ * total_winner:
+ *	Code for a winner
+ */
+total_winner()
+{
+    register THING *obj;
+    register int worth = 0;
+    register char c;
+    register int oldpurse;
+
+    clear();
+    standout();
+    addstr("                                                               \n");
+    addstr("  @   @               @   @           @          @@@  @     @  \n");
+    addstr("  @   @               @@ @@           @           @   @     @  \n");
+    addstr("  @   @  @@@  @   @   @ @ @  @@@   @@@@  @@@      @  @@@    @  \n");
+    addstr("   @@@@ @   @ @   @   @   @     @ @   @ @   @     @   @     @  \n");
+    addstr("      @ @   @ @   @   @   @  @@@@ @   @ @@@@@     @   @     @  \n");
+    addstr("  @   @ @   @ @  @@   @   @ @   @ @   @ @         @   @  @     \n");
+    addstr("   @@@   @@@   @@ @   @   @  @@@@  @@@@  @@@     @@@   @@   @  \n");
+    addstr("                                                               \n");
+    addstr("     Congratulations, you have made it to the light of day!    \n");
+    standend();
+    addstr("\nYou have joined the elite ranks of those who have escaped the\n");
+    addstr("Dungeons of Doom alive.  You journey home and sell all your loot at\n");
+    addstr("a great profit and are admitted to the fighters guild.\n");
+    mvaddstr(LINES - 1, 0, "--Press space to continue--");
+    refresh();
+    wait_for(' ');
+    clear();
+    mvaddstr(0, 0, "   Worth  Item");
+    oldpurse = purse;
+    for (c = 'a', obj = pack; obj != NULL; c++, obj = next(obj))
+    {
+	switch (obj->o_type)
+	{
+	    case FOOD:
+		worth = 2 * obj->o_count;
+	    when WEAPON:
+		switch (obj->o_which)
+		{
+		    case MACE: worth = 8;
+		    when SWORD: worth = 15;
+		    when CROSSBOW: worth = 30;
+		    when ARROW: worth = 1;
+		    when DAGGER: worth = 2;
+		    when TWOSWORD: worth = 75;
+		    when DART: worth = 1;
+		    when BOW: worth = 15;
+		    when BOLT: worth = 1;
+		    when SPEAR: worth = 5;
+		}
+		worth *= 3 * (obj->o_hplus + obj->o_dplus) + obj->o_count;
+		obj->o_flags |= ISKNOW;
+	    when ARMOR:
+		switch (obj->o_which)
+		{
+		    case LEATHER: worth = 20;
+		    when RING_MAIL: worth = 25;
+		    when STUDDED_LEATHER: worth = 20;
+		    when SCALE_MAIL: worth = 30;
+		    when CHAIN_MAIL: worth = 75;
+		    when SPLINT_MAIL: worth = 80;
+		    when BANDED_MAIL: worth = 90;
+		    when PLATE_MAIL: worth = 150;
+		}
+		worth += (9 - obj->o_ac) * 100;
+		worth += (10 * (a_class[obj->o_which] - obj->o_ac));
+		obj->o_flags |= ISKNOW;
+	    when SCROLL:
+		worth = s_magic[obj->o_which].mi_worth;
+		worth *= obj->o_count;
+		if (!s_know[obj->o_which])
+		    worth /= 2;
+		s_know[obj->o_which] = TRUE;
+	    when POTION:
+		worth = p_magic[obj->o_which].mi_worth;
+		worth *= obj->o_count;
+		if (!p_know[obj->o_which])
+		    worth /= 2;
+		p_know[obj->o_which] = TRUE;
+	    when RING:
+		worth = r_magic[obj->o_which].mi_worth;
+		if (obj->o_which == R_ADDSTR || obj->o_which == R_ADDDAM ||
+		    obj->o_which == R_PROTECT || obj->o_which == R_ADDHIT)
+			if (obj->o_ac > 0)
+			    worth += obj->o_ac * 100;
+			else
+			    worth = 10;
+		if (!(obj->o_flags & ISKNOW))
+		    worth /= 2;
+		obj->o_flags |= ISKNOW;
+		r_know[obj->o_which] = TRUE;
+	    when STICK:
+		worth = ws_magic[obj->o_which].mi_worth;
+		worth += 20 * obj->o_charges;
+		if (!(obj->o_flags & ISKNOW))
+		    worth /= 2;
+		obj->o_flags |= ISKNOW;
+		ws_know[obj->o_which] = TRUE;
+	    when AMULET:
+		worth = 1000;
+	}
+	if (worth < 0)
+	    worth = 0;
+	mvprintw(c - 'a' + 1, 0, "%c) %5d  %s", c, worth, inv_name(obj, FALSE));
+	purse += worth;
+    }
+    mvprintw(c - 'a' + 1, 0,"   %5d  Gold Pieces          ", oldpurse);
+    refresh();
+    score(purse, 2, 0);
+    exit(0);
+}
+
+/*
+ * killname:
+ *	Convert a code to a monster name
+ */
+char *
+killname(monst, doart)
+register char monst;
+bool doart;
+{
+    register const char *sp;
+    register bool article;
+
+    sp = prbuf;
+    article = TRUE;
+    switch (monst)
+    {
+	case 'a':
+	    sp = "arrow";
+	when 'b':
+	    sp = "bolt";
+	when 'd':
+	    sp = "dart";
+	when 's':
+	    sp = "starvation";
+	    article = FALSE;
+	otherwise:
+	    if (monst >= 'A' && monst <= 'Z')
+		sp = monsters[monst-'A'].m_name;
+	    else
+	    {
+		sp = "God";
+		article = FALSE;
+	    }
+    }
+    if (doart && article)
+	sprintf(prbuf, "a%s ", vowelstr(sp));
+    else
+	prbuf[0] = '\0';
+    strcat(prbuf, sp);
+    return prbuf;
+}