Hush Full Node software. We were censored from Github, this is where all development happens now.
https://hush.is
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
464 lines
11 KiB
464 lines
11 KiB
// Copyright (c) 2016-2022 The Hush developers
|
|
// Distributed under the GPLv3 software license, see the accompanying
|
|
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
/*
|
|
* File for the fun ends
|
|
* Death or a total win
|
|
*
|
|
* @(#)rip.c 4.57 (Berkeley) 02/05/99
|
|
*
|
|
* Rogue: Exploring the Dungeons of Doom
|
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
|
* All rights reserved.
|
|
*
|
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
|
*/
|
|
|
|
//#include <stdlib.h>
|
|
//#include <string.h>
|
|
//#include <time.h>
|
|
#include <signal.h>
|
|
//#include <sys/types.h>
|
|
//#include <ctype.h>
|
|
//#include <fcntl.h>
|
|
//#include <curses.h>
|
|
#include "rogue.h"
|
|
#include "score.h"
|
|
|
|
static char *rip[] = {
|
|
" __________\n",
|
|
" / \\\n",
|
|
" / REST \\\n",
|
|
" / IN \\\n",
|
|
" / PEACE \\\n",
|
|
" / \\\n",
|
|
" | |\n",
|
|
" | |\n",
|
|
" | killed by a |\n",
|
|
" | |\n",
|
|
" | 1980 |\n",
|
|
" *| * * * | *\n",
|
|
" ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______\n",
|
|
0
|
|
};
|
|
|
|
/*
|
|
* score:
|
|
* Figure score and post it.
|
|
*/
|
|
/* VARARGS2 */
|
|
|
|
void
|
|
score(struct rogue_state *rs,int amount, int flags, char monst)
|
|
{
|
|
SCORE *scp;
|
|
int i;
|
|
SCORE *sc2;
|
|
SCORE *top_ten, *endp;
|
|
if ( rs->guiflag == 0 )
|
|
return;
|
|
# ifdef MASTER
|
|
int prflags = 0;
|
|
# endif
|
|
void (*fp)(int);
|
|
unsigned int uid;
|
|
static char *reason[] = {
|
|
"killed",
|
|
"quit",
|
|
"A total winner",
|
|
"killed with Amulet"
|
|
};
|
|
|
|
start_score();
|
|
|
|
if (flags >= 0
|
|
#ifdef MASTER
|
|
|| wizard
|
|
#endif
|
|
)
|
|
{
|
|
mvaddstr(LINES - 1, 0 , "[Press return to continue]");
|
|
refresh();
|
|
wgetnstr(stdscr,prbuf,80);
|
|
endwin();
|
|
printf("\n");
|
|
resetltchars();
|
|
/*
|
|
* free up space to "guarantee" there is space for the top_ten
|
|
*/
|
|
delwin(stdscr);
|
|
delwin(curscr);
|
|
if (hw != NULL)
|
|
delwin(hw);
|
|
hw = NULL;
|
|
}
|
|
|
|
top_ten = (SCORE *) malloc(numscores * sizeof (SCORE));
|
|
endp = &top_ten[numscores];
|
|
for (scp = top_ten; scp < endp; scp++)
|
|
{
|
|
scp->sc_score = 0;
|
|
for (i = 0; i < MAXSTR; i++)
|
|
scp->sc_name[i] = (unsigned char) rnd(255);
|
|
scp->sc_flags = RN;
|
|
scp->sc_level = RN;
|
|
scp->sc_monster = (unsigned short) RN;
|
|
scp->sc_uid = RN;
|
|
}
|
|
|
|
signal(SIGINT, SIG_DFL);
|
|
|
|
#ifdef MASTER
|
|
if (wizard)
|
|
if (strcmp(prbuf, "names") == 0)
|
|
prflags = 1;
|
|
else if (strcmp(prbuf, "edit") == 0)
|
|
prflags = 2;
|
|
#endif
|
|
rd_score(top_ten);
|
|
/*
|
|
* Insert her in list if need be
|
|
*/
|
|
sc2 = NULL;
|
|
if (!noscore)
|
|
{
|
|
uid = md_getuid();
|
|
for (scp = top_ten; scp < endp; scp++)
|
|
if (amount > scp->sc_score)
|
|
break;
|
|
else if (!allscore && /* only one score per nowin uid */
|
|
flags != 2 && scp->sc_uid == uid && scp->sc_flags != 2)
|
|
scp = endp;
|
|
if (scp < endp)
|
|
{
|
|
if (flags != 2 && !allscore)
|
|
{
|
|
for (sc2 = scp; sc2 < endp; sc2++)
|
|
{
|
|
if (sc2->sc_uid == uid && sc2->sc_flags != 2)
|
|
break;
|
|
}
|
|
if (sc2 >= endp)
|
|
sc2 = endp - 1;
|
|
}
|
|
else
|
|
sc2 = endp - 1;
|
|
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
|
|
*/
|
|
if (flags != -1)
|
|
putchar('\n');
|
|
printf("Top %s %s:\n", Numname, allscore ? "Scores" : "Rogueists");
|
|
printf(" Score Name\n");
|
|
for (scp = top_ten; scp < endp; scp++)
|
|
{
|
|
if (scp->sc_score) {
|
|
if (sc2 == scp)
|
|
md_raw_standout();
|
|
printf("%2d %5d %s: %s on level %d", (int) (scp - top_ten + 1),
|
|
scp->sc_score, scp->sc_name, reason[scp->sc_flags],
|
|
scp->sc_level);
|
|
if (scp->sc_flags == 0 || scp->sc_flags == 3)
|
|
printf(" by %s", killname((char) scp->sc_monster, TRUE));
|
|
#ifdef MASTER
|
|
if (prflags == 1)
|
|
{
|
|
printf(" (%s)", md_getrealname(scp->sc_uid));
|
|
}
|
|
else if (prflags == 2)
|
|
{
|
|
fflush(stdout);
|
|
if ( fgets(prbuf,10,stdin) != 0 )
|
|
fprintf(stderr,"fgets error\n");
|
|
if (prbuf[0] == 'd')
|
|
{
|
|
for (sc2 = scp; sc2 < endp - 1; sc2++)
|
|
*sc2 = *(sc2 + 1);
|
|
sc2 = endp - 1;
|
|
sc2->sc_score = 0;
|
|
for (i = 0; i < MAXSTR; i++)
|
|
sc2->sc_name[i] = (char) rnd(255);
|
|
sc2->sc_flags = RN;
|
|
sc2->sc_level = RN;
|
|
sc2->sc_monster = (unsigned short) RN;
|
|
scp--;
|
|
}
|
|
}
|
|
else
|
|
#endif /* MASTER */
|
|
printf(".");
|
|
if (sc2 == scp)
|
|
md_raw_standend();
|
|
putchar('\n');
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
/*
|
|
* Update the list file
|
|
*/
|
|
if (sc2 != NULL)
|
|
{
|
|
if (lock_sc())
|
|
{
|
|
fp = signal(SIGINT, SIG_IGN);
|
|
wr_score(top_ten);
|
|
unlock_sc();
|
|
signal(SIGINT, fp);
|
|
}
|
|
}
|
|
free(top_ten);
|
|
}
|
|
|
|
/*
|
|
* death:
|
|
* Do something really fun when he dies
|
|
*/
|
|
|
|
void
|
|
death(struct rogue_state *rs,char monst)
|
|
{
|
|
char **dp, *killer;
|
|
struct tm *lt;
|
|
static time_t date;
|
|
//struct tm *localtime(const time_t *);
|
|
if ( rs->guiflag == 0 )
|
|
{
|
|
//fprintf(stderr,"death during replay by (%c)\n",monst); //sleep(3);
|
|
rs->replaydone = (uint32_t)time(NULL);
|
|
return;
|
|
}
|
|
signal(SIGINT, SIG_IGN);
|
|
purse -= purse / 10;
|
|
signal(SIGINT, leave);
|
|
clear();
|
|
killer = killname(monst, FALSE);
|
|
if (!tombstone)
|
|
{
|
|
mvprintw(LINES - 2, 0, "Killed by ");
|
|
killer = killname(monst, FALSE);
|
|
if (monst != 's' && monst != 'h')
|
|
printw("a%s ", vowelstr(killer));
|
|
printw("%s with %d gold", killer, purse);
|
|
}
|
|
else
|
|
{
|
|
time(&date);
|
|
lt = localtime(&date);
|
|
move(8, 0);
|
|
dp = rip;
|
|
while (*dp)
|
|
addstr(*dp++);
|
|
mvaddstr(17, center(killer), killer);
|
|
if (monst == 's' || monst == 'h')
|
|
mvaddch(16, 32, ' ');
|
|
else
|
|
mvaddstr(16, 33, vowelstr(killer));
|
|
mvaddstr(14, center(whoami), whoami);
|
|
sprintf(prbuf, "%d Au", purse);
|
|
move(15, center(prbuf));
|
|
addstr(prbuf);
|
|
sprintf(prbuf, "%4d", 1900+lt->tm_year);
|
|
mvaddstr(18, 26, prbuf);
|
|
}
|
|
move(LINES - 1, 0);
|
|
refresh();
|
|
score(rs,purse, amulet ? 3 : 0, monst);
|
|
rogue_bailout(rs);
|
|
printf("[Press return to continue]");
|
|
fflush(stdout);
|
|
if ( fgets(prbuf,10,stdin) != 0 )
|
|
;
|
|
my_exit(0);
|
|
}
|
|
|
|
/*
|
|
* center:
|
|
* Return the index to center the given string
|
|
*/
|
|
int
|
|
center(char *str)
|
|
{
|
|
return 28 - (((int)strlen(str) + 1) / 2);
|
|
}
|
|
|
|
/*
|
|
* total_winner:
|
|
* Code for a winner
|
|
*/
|
|
|
|
void
|
|
total_winner(struct rogue_state *rs)
|
|
{
|
|
THING *obj;
|
|
struct obj_info *op;
|
|
int worth = 0;
|
|
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(rs,' ');
|
|
clear();
|
|
mvaddstr(0, 0, " Worth Item\n");
|
|
oldpurse = purse;
|
|
for (obj = pack; obj != NULL; obj = next(obj))
|
|
{
|
|
switch (obj->o_type)
|
|
{
|
|
case FOOD:
|
|
worth = 2 * obj->o_count;
|
|
when WEAPON:
|
|
worth = weap_info[obj->o_which].oi_worth;
|
|
worth *= 3 * (obj->o_hplus + obj->o_dplus) + obj->o_count;
|
|
obj->o_flags |= ISKNOW;
|
|
when ARMOR:
|
|
worth = arm_info[obj->o_which].oi_worth;
|
|
worth += (9 - obj->o_arm) * 100;
|
|
worth += (10 * (a_class[obj->o_which] - obj->o_arm));
|
|
obj->o_flags |= ISKNOW;
|
|
when SCROLL:
|
|
worth = scr_info[obj->o_which].oi_worth;
|
|
worth *= obj->o_count;
|
|
op = &scr_info[obj->o_which];
|
|
if (!op->oi_know)
|
|
worth /= 2;
|
|
op->oi_know = TRUE;
|
|
when POTION:
|
|
worth = pot_info[obj->o_which].oi_worth;
|
|
worth *= obj->o_count;
|
|
op = &pot_info[obj->o_which];
|
|
if (!op->oi_know)
|
|
worth /= 2;
|
|
op->oi_know = TRUE;
|
|
when RING:
|
|
op = &ring_info[obj->o_which];
|
|
worth = op->oi_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_arm > 0)
|
|
worth += obj->o_arm * 100;
|
|
else
|
|
worth = 10;
|
|
}
|
|
if (!(obj->o_flags & ISKNOW))
|
|
worth /= 2;
|
|
obj->o_flags |= ISKNOW;
|
|
op->oi_know = TRUE;
|
|
when STICK:
|
|
op = &ws_info[obj->o_which];
|
|
worth = op->oi_worth;
|
|
worth += 20 * obj->o_charges;
|
|
if (!(obj->o_flags & ISKNOW))
|
|
worth /= 2;
|
|
obj->o_flags |= ISKNOW;
|
|
op->oi_know = TRUE;
|
|
when AMULET:
|
|
worth = 1000;
|
|
}
|
|
if (worth < 0)
|
|
worth = 0;
|
|
printw("%c) %5d %s\n", obj->o_packch, worth, inv_name(obj, FALSE));
|
|
purse += worth;
|
|
}
|
|
printw(" %5d Gold Pieces ", oldpurse);
|
|
refresh();
|
|
score(rs,purse, 2, ' ');
|
|
my_exit(0);
|
|
}
|
|
|
|
/*
|
|
* killname:
|
|
* Convert a code to a monster name
|
|
*/
|
|
char *
|
|
killname(char monst, bool doart)
|
|
{
|
|
struct h_list *hp;
|
|
char *sp;
|
|
bool article;
|
|
static struct h_list nlist[] = {
|
|
{'a', "arrow", TRUE},
|
|
{'b', "bolt", TRUE},
|
|
{'d', "dart", TRUE},
|
|
{'h', "hypothermia", FALSE},
|
|
{'s', "starvation", FALSE},
|
|
{'\0'}
|
|
};
|
|
|
|
if (isupper(monst))
|
|
{
|
|
sp = monsters[monst-'A'].m_name;
|
|
article = TRUE;
|
|
}
|
|
else
|
|
{
|
|
sp = "Wally the Wonder Badger";
|
|
article = FALSE;
|
|
for (hp = nlist; hp->h_ch; hp++)
|
|
if (hp->h_ch == monst)
|
|
{
|
|
sp = hp->h_desc;
|
|
article = hp->h_print;
|
|
break;
|
|
}
|
|
}
|
|
if (doart && article)
|
|
sprintf(prbuf, "a%s ", vowelstr(sp));
|
|
else
|
|
prbuf[0] = '\0';
|
|
strcat(prbuf, sp);
|
|
return prbuf;
|
|
}
|
|
|
|
/*
|
|
* death_monst:
|
|
* Return a monster appropriate for a random death.
|
|
*/
|
|
char
|
|
death_monst()
|
|
{
|
|
static char poss[] =
|
|
{
|
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
|
|
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
|
'Y', 'Z', 'a', 'b', 'h', 'd', 's',
|
|
' ' /* This is provided to generate the "Wally the Wonder Badger"
|
|
message for killer */
|
|
};
|
|
|
|
return poss[rnd(sizeof poss / sizeof (char))];
|
|
}
|
|
|