From bcced3608bdd120315d4ed1d9b9478f7caa4a2f1 Mon Sep 17 00:00:00 2001 From: jtc Date: Fri, 21 Oct 1994 21:19:39 +0000 Subject: phantasia(6), from 44lite --- phantasia/gamesupport.c | 722 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 722 insertions(+) create mode 100644 phantasia/gamesupport.c (limited to 'phantasia/gamesupport.c') diff --git a/phantasia/gamesupport.c b/phantasia/gamesupport.c new file mode 100644 index 00000000..c7481ef7 --- /dev/null +++ b/phantasia/gamesupport.c @@ -0,0 +1,722 @@ +/* + * gamesupport.c - auxiliary routines for support of Phantasia + */ + +#include "include.h" + +/************************************************************************ +/ +/ FUNCTION NAME: changestats() +/ +/ FUNCTION: examine/change statistics for a player +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: +/ bool ingameflag - set if called while playing game (Wizard only) +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: freerecord(), writerecord(), descrstatus(), truncstring(), +/ time(), more(), wmove(), wclear(), strcmp(), printw(), strcpy(), +/ infloat(), waddstr(), cleanup(), findname(), userlist(), mvprintw(), +/ localtime(), getanswer(), descrtype(), getstring() +/ +/ GLOBAL INPUTS: LINES, *Login, Other, Wizard, Player, *stdscr, Databuf[], +/ Fileloc +/ +/ GLOBAL OUTPUTS: Echo +/ +/ DESCRIPTION: +/ Prompt for player name to examine/change. +/ If the name is NULL, print a list of all players. +/ If we are called from within the game, check for the +/ desired name being the same as the current player's name. +/ Only the 'Wizard' may alter players. +/ Items are changed only if a non-zero value is specified. +/ To change an item to 0, use 0.1; it will be truncated later. +/ +/ Players may alter their names and passwords, if the following +/ are true: +/ - current login matches the character's logins +/ - the password is known +/ - the player is not in the middle of the game (ingameflag == FALSE) +/ +/ The last condition is imposed for two reasons: +/ - the game could possibly get a bit hectic if a player were +/ continually changing his/her name +/ - another player structure would be necessary to check for names +/ already in use +/ +/************************************************************************/ + +changestats(ingameflag) +bool ingameflag; +{ +static char flag[2] = /* for printing values of bools */ + {'F', 'T'}; +register struct player *playerp;/* pointer to structure to alter */ +register char *prompt; /* pointer to prompt string */ +int c; /* input */ +int today; /* day of year of today */ +int temp; /* temporary variable */ +long loc; /* location in player file */ +long now; /* time now */ +double dtemp; /* temporary variable */ +bool *bptr; /* pointer to bool item to change */ +double *dptr; /* pointer to double item to change */ +short *sptr; /* pointer to short item to change */ + + clear(); + + for (;;) + /* get name of player to examine/alter */ + { + mvaddstr(5, 0, "Which character do you want to look at ? "); + getstring(Databuf, SZ_DATABUF); + truncstring(Databuf); + + if (Databuf[0] == '\0') + userlist(ingameflag); + else + break; + } + + loc = -1L; + + if (!ingameflag) + /* use 'Player' structure */ + playerp = &Player; + else if (strcmp(Databuf, Player.p_name) == 0) + /* alter/examine current player */ + { + playerp = &Player; + loc = Fileloc; + } + else + /* use 'Other' structure */ + playerp = &Other; + + /* find player on file */ + if (loc < 0L && (loc = findname(Databuf, playerp)) < 0L) + /* didn't find player */ + { + clear(); + mvaddstr(11, 0, "Not found."); + return; + } + + time(&now); + today = localtime(&now)->tm_yday; + + clear(); + + for (;;) + /* print player structure, and prompt for action */ + { + mvprintw(0, 0,"A:Name %s\n", playerp->p_name); + + if (Wizard) + printw("B:Password %s\n", playerp->p_password); + else + addstr("B:Password XXXXXXXX\n"); + + printw(" :Login %s\n", playerp->p_login); + + printw("C:Experience %.0f\n", playerp->p_experience); + printw("D:Level %.0f\n", playerp->p_level); + printw("E:Strength %.0f\n", playerp->p_strength); + printw("F:Sword %.0f\n", playerp->p_sword); + printw(" :Might %.0f\n", playerp->p_might); + printw("G:Energy %.0f\n", playerp->p_energy); + printw("H:Max-Energy %.0f\n", playerp->p_maxenergy); + printw("I:Shield %.0f\n", playerp->p_shield); + printw("J:Quickness %.0f\n", playerp->p_quickness); + printw("K:Quicksilver %.0f\n", playerp->p_quksilver); + printw(" :Speed %.0f\n", playerp->p_speed); + printw("L:Magic Level %.0f\n", playerp->p_magiclvl); + printw("M:Mana %.0f\n", playerp->p_mana); + printw("N:Brains %.0f\n", playerp->p_brains); + + if (Wizard || playerp->p_specialtype != SC_VALAR) + mvaddstr(0, 40, descrstatus(playerp)); + + mvprintw(1, 40, "O:Poison %0.3f\n", playerp->p_poison); + mvprintw(2, 40, "P:Gold %.0f\n", playerp->p_gold); + mvprintw(3, 40, "Q:Gem %.0f\n", playerp->p_gems); + mvprintw(4, 40, "R:Sin %0.3f\n", playerp->p_sin); + if (Wizard) + { + mvprintw(5, 40, "S:X-coord %.0f\n", playerp->p_x); + mvprintw(6, 40, "T:Y-coord %.0f\n", playerp->p_y); + } + else + { + mvaddstr(5, 40, "S:X-coord ?\n"); + mvaddstr(6, 40, "T:Y-coord ?\n"); + } + + mvprintw(7, 40, "U:Age %ld\n", playerp->p_age); + mvprintw(8, 40, "V:Degenerated %d\n", playerp->p_degenerated); + + mvprintw(9, 40, "W:Type %d (%s)\n", + playerp->p_type, descrtype(playerp, FALSE) + 1); + mvprintw(10, 40, "X:Special Type %d\n", playerp->p_specialtype); + mvprintw(11, 40, "Y:Lives %d\n", playerp->p_lives); + mvprintw(12, 40, "Z:Crowns %d\n", playerp->p_crowns); + mvprintw(13, 40, "0:Charms %d\n", playerp->p_charms); + mvprintw(14, 40, "1:Amulets %d\n", playerp->p_amulets); + mvprintw(15, 40, "2:Holy Water %d\n", playerp->p_holywater); + + temp = today - playerp->p_lastused; + if (temp < 0) + /* last year */ + temp += 365; + mvprintw(16, 40, "3:Lastused %d (%d)\n", playerp->p_lastused, temp); + + mvprintw(18, 8, "4:Palantir %c 5:Blessing %c 6:Virgin %c 7:Blind %c", + flag[playerp->p_palantir], + flag[playerp->p_blessing], + flag[playerp->p_virgin], + flag[playerp->p_blindness]); + + if (!Wizard) + mvprintw(19, 8, "8:Ring %c", + flag[playerp->p_ring.ring_type != R_NONE]); + else + mvprintw(19, 8, "8:Ring %d 9:Duration %d", + playerp->p_ring.ring_type, playerp->p_ring.ring_duration); + + if (!Wizard + /* not wizard */ + && (ingameflag || strcmp(Login, playerp->p_login) != 0)) + /* in game or not examining own character */ + { + if (ingameflag) + { + more(LINES - 1); + clear(); + return; + } + else + cleanup(TRUE); + /*NOTREACHED*/ + } + + mvaddstr(20, 0, "!:Quit ?:Delete"); + mvaddstr(21, 0, "What would you like to change ? "); + + if (Wizard) + c = getanswer(" ", TRUE); + else + /* examining own player; allow to change name and password */ + c = getanswer("!BA", FALSE); + + switch (c) + { + case 'A': /* change name */ + case 'B': /* change password */ + if (!Wizard) + /* prompt for password */ + { + mvaddstr(23, 0, "Password ? "); + Echo = FALSE; + getstring(Databuf, 9); + Echo = TRUE; + if (strcmp(Databuf, playerp->p_password) != 0) + continue; + } + + if (c == 'A') + /* get new name */ + { + mvaddstr(23, 0, "New name: "); + getstring(Databuf, SZ_NAME); + truncstring(Databuf); + if (Databuf[0] != '\0') + if (Wizard || findname(Databuf, &Other) < 0L) + strcpy(playerp->p_name, Databuf); + } + else + /* get new password */ + { + if (!Wizard) + Echo = FALSE; + + do + /* get two copies of new password until they match */ + { + /* get first copy */ + mvaddstr(23, 0, "New password ? "); + getstring(Databuf, SZ_PASSWORD); + if (Databuf[0] == '\0') + break; + + /* get second copy */ + mvaddstr(23, 0, "One more time ? "); + getstring(playerp->p_password, SZ_PASSWORD); + } + while (strcmp(playerp->p_password, Databuf) != 0); + + Echo = TRUE; + } + + continue; + + case 'C': /* change experience */ + prompt = "experience"; + dptr = &playerp->p_experience; + goto DALTER; + + case 'D': /* change level */ + prompt = "level"; + dptr = &playerp->p_level; + goto DALTER; + + case 'E': /* change strength */ + prompt = "strength"; + dptr = &playerp->p_strength; + goto DALTER; + + case 'F': /* change swords */ + prompt = "sword"; + dptr = &playerp->p_sword; + goto DALTER; + + case 'G': /* change energy */ + prompt = "energy"; + dptr = &playerp->p_energy; + goto DALTER; + + case 'H': /* change maximum energy */ + prompt = "max energy"; + dptr = &playerp->p_maxenergy; + goto DALTER; + + case 'I': /* change shields */ + prompt = "shield"; + dptr = &playerp->p_shield; + goto DALTER; + + case 'J': /* change quickness */ + prompt = "quickness"; + dptr = &playerp->p_quickness; + goto DALTER; + + case 'K': /* change quicksilver */ + prompt = "quicksilver"; + dptr = &playerp->p_quksilver; + goto DALTER; + + case 'L': /* change magic */ + prompt = "magic level"; + dptr = &playerp->p_magiclvl; + goto DALTER; + + case 'M': /* change mana */ + prompt = "mana"; + dptr = &playerp->p_mana; + goto DALTER; + + case 'N': /* change brains */ + prompt = "brains"; + dptr = &playerp->p_brains; + goto DALTER; + + case 'O': /* change poison */ + prompt = "poison"; + dptr = &playerp->p_poison; + goto DALTER; + + case 'P': /* change gold */ + prompt = "gold"; + dptr = &playerp->p_gold; + goto DALTER; + + case 'Q': /* change gems */ + prompt = "gems"; + dptr = &playerp->p_gems; + goto DALTER; + + case 'R': /* change sin */ + prompt = "sin"; + dptr = &playerp->p_sin; + goto DALTER; + + case 'S': /* change x coord */ + prompt = "x"; + dptr = &playerp->p_x; + goto DALTER; + + case 'T': /* change y coord */ + prompt = "y"; + dptr = &playerp->p_y; + goto DALTER; + + case 'U': /* change age */ + mvprintw(23, 0, "age = %ld; age = ", playerp->p_age); + dtemp = infloat(); + if (dtemp != 0.0) + playerp->p_age = (long) dtemp; + continue; + + case 'V': /* change degen */ + mvprintw(23, 0, "degen = %d; degen = ", playerp->p_degenerated); + dtemp = infloat(); + if (dtemp != 0.0) + playerp->p_degenerated = (int) dtemp; + continue; + + case 'W': /* change type */ + prompt = "type"; + sptr = &playerp->p_type; + goto SALTER; + + case 'X': /* change special type */ + prompt = "special type"; + sptr = &playerp->p_specialtype; + goto SALTER; + + case 'Y': /* change lives */ + prompt = "lives"; + sptr = &playerp->p_lives; + goto SALTER; + + case 'Z': /* change crowns */ + prompt = "crowns"; + sptr = &playerp->p_crowns; + goto SALTER; + + case '0': /* change charms */ + prompt = "charm"; + sptr = &playerp->p_charms; + goto SALTER; + + case '1': /* change amulet */ + prompt = "amulet"; + sptr = &playerp->p_amulets; + goto SALTER; + + case '2': /* change holy water */ + prompt = "holy water"; + sptr = &playerp->p_holywater; + goto SALTER; + + case '3': /* change last-used */ + prompt = "last-used"; + sptr = &playerp->p_lastused; + goto SALTER; + + case '4': /* change palantir */ + prompt = "palantir"; + bptr = &playerp->p_palantir; + goto BALTER; + + case '5': /* change blessing */ + prompt = "blessing"; + bptr = &playerp->p_blessing; + goto BALTER; + + case '6': /* change virgin */ + prompt = "virgin"; + bptr = &playerp->p_virgin; + goto BALTER; + + case '7': /* change blindness */ + prompt = "blindness"; + bptr = &playerp->p_blindness; + goto BALTER; + + case '8': /* change ring type */ + prompt = "ring-type"; + sptr = &playerp->p_ring.ring_type; + goto SALTER; + + case '9': /* change ring duration */ + prompt = "ring-duration"; + sptr = &playerp->p_ring.ring_duration; + goto SALTER; + + case '!': /* quit, update */ + if (Wizard && + (!ingameflag || playerp != &Player)) + /* turn off status if not modifying self */ + { + playerp->p_status = S_OFF; + playerp->p_tampered = T_OFF; + } + + writerecord(playerp, loc); + clear(); + return; + + case '?': /* delete player */ + if (ingameflag && playerp == &Player) + /* cannot delete self */ + continue; + + freerecord(playerp, loc); + clear(); + return; + + default: + continue; + } +DALTER: + mvprintw(23, 0, "%s = %f; %s = ", prompt, *dptr, prompt); + dtemp = infloat(); + if (dtemp != 0.0) + *dptr = dtemp; + continue; + +SALTER: + mvprintw(23, 0, "%s = %d; %s = ", prompt, *sptr, prompt); + dtemp = infloat(); + if (dtemp != 0.0) + *sptr = (short) dtemp; + continue; + +BALTER: + mvprintw(23, 0, "%s = %c; %s = ", prompt, flag[*bptr], prompt); + c = getanswer("\nTF", TRUE); + if (c == 'T') + *bptr = TRUE; + else if (c == 'F') + *bptr = FALSE; + continue; + } +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: monstlist() +/ +/ FUNCTION: print a monster listing +/ +/ AUTHOR: E. A. Estes, 2/27/86 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: puts(), fread(), fseek(), printf() +/ +/ GLOBAL INPUTS: Curmonster, *Monstfp +/ +/ GLOBAL OUTPUTS: none +/ +/ DESCRIPTION: +/ Read monster file, and print a monster listing on standard output. +/ +/************************************************************************/ + +monstlist() +{ +register int count = 0; /* count in file */ + + puts(" #) Name Str Brain Quick Energy Exper Treas Type Flock%\n"); + fseek(Monstfp, 0L, 0); + while (fread((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp) == 1) + printf("%2d) %-20.20s%4.0f %4.0f %2.0f %5.0f %5.0f %2d %2d %3.0f\n", count++, + Curmonster.m_name, Curmonster.m_strength, Curmonster.m_brains, + Curmonster.m_speed, Curmonster.m_energy, Curmonster.m_experience, + Curmonster.m_treasuretype, Curmonster.m_type, Curmonster.m_flock); +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: scorelist() +/ +/ FUNCTION: print player score board +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: fread(), fopen(), printf(), fclose() +/ +/ GLOBAL INPUTS: +/ +/ GLOBAL OUTPUTS: none +/ +/ DESCRIPTION: +/ Read the scoreboard file and print the contents. +/ +/************************************************************************/ + +scorelist() +{ +struct scoreboard sbuf; /* for reading entries */ +register FILE *fp; /* to open the file */ + + if ((fp = fopen(_PATH_SCORE, "r")) != NULL) + { + while (fread((char *) &sbuf, SZ_SCORESTRUCT, 1, fp) == 1) + printf("%-20s (%-9s) Level: %6.0f Type: %s\n", + sbuf.sb_name, sbuf.sb_login, sbuf.sb_level, sbuf.sb_type); + fclose(fp); + } +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: activelist() +/ +/ FUNCTION: print list of active players to standard output +/ +/ AUTHOR: E. A. Estes, 3/7/86 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: descrstatus(), fread(), fseek(), printf(), descrtype() +/ +/ GLOBAL INPUTS: Other, *Playersfp +/ +/ GLOBAL OUTPUTS: none +/ +/ DESCRIPTION: +/ Read player file, and print list of active records to standard output. +/ +/************************************************************************/ + +activelist() +{ + fseek(Playersfp, 0L, 0); + printf("Current characters on file are:\n\n"); + + while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) + if (Other.p_status != S_NOTUSED) + printf("%-20s (%-9s) Level: %6.0f %s (%s)\n", + Other.p_name, Other.p_login, Other.p_level, + descrtype(&Other, FALSE), descrstatus(&Other)); + +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: purgeoldplayers() +/ +/ FUNCTION: purge inactive players from player file +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: freerecord(), time(), fread(), fseek(), localtime() +/ +/ GLOBAL INPUTS: Other, *Playersfp +/ +/ GLOBAL OUTPUTS: none +/ +/ DESCRIPTION: +/ Delete characters which have not been used with the last +/ three weeks. +/ +/************************************************************************/ + +purgeoldplayers() +{ +int today; /* day of year for today */ +int daysold; /* how many days since the character has been used */ +long ltime; /* time in seconds */ +long loc = 0L; /* location in file */ + + time(<ime); + today = localtime(<ime)->tm_yday; + + for (;;) + { + fseek(Playersfp, loc, 0); + if (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) != 1) + break; + + daysold = today - Other.p_lastused; + if (daysold < 0) + daysold += 365; + + if (daysold > N_DAYSOLD) + /* player hasn't been used in a while; delete */ + freerecord(&Other, loc); + + loc += SZ_PLAYERSTRUCT; + } +} +/* */ +/************************************************************************ +/ +/ FUNCTION NAME: enterscore() +/ +/ FUNCTION: enter player into scoreboard +/ +/ AUTHOR: E. A. Estes, 12/4/85 +/ +/ ARGUMENTS: none +/ +/ RETURN VALUE: none +/ +/ MODULES CALLED: fread(), fseek(), fopen(), error(), strcmp(), fclose(), +/ strcpy(), fwrite(), descrtype() +/ +/ GLOBAL INPUTS: Player +/ +/ GLOBAL OUTPUTS: none +/ +/ DESCRIPTION: +/ The scoreboard keeps track of the highest character on a +/ per-login basis. +/ Search the scoreboard for an entry for the current login, +/ if an entry is found, and it is lower than the current player, +/ replace it, otherwise create an entry. +/ +/************************************************************************/ + +enterscore() +{ +struct scoreboard sbuf; /* buffer to read in scoreboard entries */ +FILE *fp; /* to open scoreboard file */ +long loc = 0L; /* location in scoreboard file */ +bool found = FALSE; /* set if we found an entry for this login */ + + if ((fp = fopen(_PATH_SCORE, "r+")) != NULL) + { + while (fread((char *) &sbuf, SZ_SCORESTRUCT, 1, fp) == 1) + if (strcmp(Player.p_login, sbuf.sb_login) == 0) + { + found = TRUE; + break; + } + else + loc += SZ_SCORESTRUCT; + } + else + { + error(_PATH_SCORE); + /*NOTREACHED*/ + } + + /* + * At this point, 'loc' will either indicate a point beyond + * the end of file, or the place where the previous entry + * was found. + */ + + if ((!found) || Player.p_level > sbuf.sb_level) + /* put new entry in for this login */ + { + strcpy(sbuf.sb_login, Player.p_login); + strcpy(sbuf.sb_name, Player.p_name); + sbuf.sb_level = Player.p_level; + strcpy(sbuf.sb_type, descrtype(&Player, TRUE)); + } + + /* update entry */ + fseek(fp, loc, 0); + fwrite((char *) &sbuf, SZ_SCORESTRUCT, 1, fp); + fclose(fp); +} -- cgit v1.2.3-56-ge451