📄 misc.c
字号:
// FUNCTION NAME: descrtype()// FUNCTION: return a string specifying player type// AUTHOR: E. A. Estes, 12/4/85// ARGUMENTS:/ struct player playerp - pointer to structure for player/ bool shortflag - set if short form is desired// RETURN VALUE: pointer to string describing player type// MODULES CALLED: strcpy()// GLOBAL INPUTS: Databuf[]// GLOBAL OUTPUTS: Databuf[]// DESCRIPTION:/ Return a string describing the player type./ King, council, valar, supercedes other types./ The first character of the string is '*' if the player/ has a crown./ If 'shortflag' is TRUE, return a 3 character string.//************************************************************************/char *descrtype(playerp, shortflag)struct player *playerp;bool shortflag;{register int type; /* for caluculating result subscript */static char *results[] = /* description table */ { " Magic User", " MU", " Fighter", " F ", " Elf", " E ", " Dwarf", " D ", " Halfling", " H ", " Experimento", " EX", " Super", " S ", " King", " K ", " Council of Wise", " CW", " Ex-Valar", " EV", " Valar", " V ", " ? ", " ? " }; type = playerp->p_type; switch (playerp->p_specialtype) { case SC_NONE: type = playerp->p_type; break; case SC_KING: type = 7; break; case SC_COUNCIL: type = 8; break; case SC_EXVALAR: type = 9; break; case SC_VALAR: type = 10; break; } type *= 2; /* calculate offset */ if (type > 20) /* error */ type = 22; if (shortflag) /* use short descriptions */ ++type; if (playerp->p_crowns > 0) { strcpy(Databuf, results[type]); Databuf[0] = '*'; return(Databuf); } else return(results[type]);}/**//************************************************************************// FUNCTION NAME: findname()// FUNCTION: find location in player file of given name// AUTHOR: E. A. Estes, 12/4/85// ARGUMENTS:/ char *name - name of character to look for/ struct player *playerp - pointer of structure to fill// RETURN VALUE: location of player if found, -1 otherwise// MODULES CALLED: fread(), fseek(), strcmp()// GLOBAL INPUTS: Wizard, *Playersfp// GLOBAL OUTPUTS: none// DESCRIPTION:/ Search the player file for the player of the given name./ If player is found, fill structure with player data.//************************************************************************/longfindname(name, playerp)register char *name;register struct player *playerp;{long loc = 0; /* location in the file */ fseek(Playersfp, 0L, 0); while (fread((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) { if (strcmp(playerp->p_name, name) == 0) { if (playerp->p_status != S_NOTUSED || Wizard) /* found it */ return(loc); } loc += SZ_PLAYERSTRUCT; } return(-1);}/**//************************************************************************// FUNCTION NAME: allocrecord()// FUNCTION: find space in the player file for a new character// AUTHOR: E. A. Estes, 12/4/85// ARGUMENTS: none// RETURN VALUE: location of free space in file// MODULES CALLED: initplayer(), writerecord(), fread(), fseek()// GLOBAL INPUTS: Other, *Playersfp// GLOBAL OUTPUTS: Player// DESCRIPTION:/ Search the player file for an unused entry. If none are found,/ make one at the end of the file.//************************************************************************/longallocrecord(){long loc = 0L; /* location in file */ fseek(Playersfp, 0L, 0); while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) { if (Other.p_status == S_NOTUSED) /* found an empty record */ return(loc); else loc += SZ_PLAYERSTRUCT; } /* make a new record */ initplayer(&Other); Player.p_status = S_OFF; writerecord(&Other, loc); return(loc);}/**//************************************************************************// FUNCTION NAME: freerecord()// FUNCTION: free up a record on the player file// AUTHOR: E. A. Estes, 2/7/86// ARGUMENTS:/ struct player playerp - pointer to structure to free/ long loc - location in file to free// RETURN VALUE: none// MODULES CALLED: writerecord()// GLOBAL INPUTS: none// GLOBAL OUTPUTS: none// DESCRIPTION:/ Mark structure as not used, and update player file.//************************************************************************/freerecord(playerp, loc)struct player *playerp;long loc;{ playerp->p_name[0] = CH_MARKDELETE; playerp->p_status = S_NOTUSED; writerecord(playerp, loc);}/**//************************************************************************// FUNCTION NAME: leavegame()// FUNCTION: leave game// AUTHOR: E. A. Estes, 12/4/85// ARGUMENTS: none// RETURN VALUE: none// MODULES CALLED: freerecord(), writerecord(), cleanup()// GLOBAL INPUTS: Player, Fileloc// GLOBAL OUTPUTS: Player// DESCRIPTION:/ Mark player as inactive, and cleanup./ Do not save players below level 1.//************************************************************************/leavegame(){ if (Player.p_level < 1.0) /* delete character */ freerecord(&Player, Fileloc); else { Player.p_status = S_OFF; writerecord(&Player, Fileloc); } cleanup(TRUE); /*NOTREACHED*/}/**//************************************************************************// FUNCTION NAME: death()// FUNCTION: death routine// AUTHOR: E. A. Estes, 12/4/85// ARGUMENTS:/ char *how - pointer to string describing cause of death// RETURN VALUE: none// MODULES CALLED: freerecord(), enterscore(), more(), exit(), fread(), / fseek(), execl(), fopen(), floor(), wmove(), drandom(), wclear(), strcmp(), / fwrite(), fflush(), printw(), strcpy(), fclose(), waddstr(), cleanup(), / fprintf(), wrefresh(), getanswer(), descrtype()// GLOBAL INPUTS: Curmonster, Wizard, Player, *stdscr, Fileloc, *Monstfp// GLOBAL OUTPUTS: Player// DESCRIPTION:/ Kill off current player./ Handle rings, and multiple lives./ Print an appropriate message./ Update scoreboard, lastdead, and let other players know about/ the demise of their comrade.//************************************************************************/death(how)char *how;{FILE *fp; /* for updating various files */int ch; /* input */static char *deathmesg[] = /* add more messages here, if desired */ { "You have been wounded beyond repair. ", "You have been disemboweled. ", "You've been mashed, mauled, and spit upon. (You're dead.)\n", "You died! ", "You're a complete failure -- you've died!!\n", "You have been dealt a fatal blow! " }; clear(); if (strcmp(how, "Stupidity") != 0) { if (Player.p_level > 9999.0) /* old age */ addstr("Characters must be retired upon reaching level 10000. Sorry."); else if (Player.p_lives > 0) /* extra lives */ { addstr("You should be more cautious. You've been killed.\n"); printw("You only have %d more chance(s).\n", --Player.p_lives); more(3); Player.p_energy = Player.p_maxenergy; return; } else if (Player.p_specialtype == SC_VALAR) { addstr("You had your chances, but Valar aren't totally\n"); addstr("immortal. You are now left to wither and die . . .\n"); more(3); Player.p_brains = Player.p_level / 25.0; Player.p_energy = Player.p_maxenergy /= 5.0; Player.p_quksilver = Player.p_sword = 0.0; Player.p_specialtype = SC_COUNCIL; return; } else if (Player.p_ring.ring_inuse && (Player.p_ring.ring_type == R_DLREG || Player.p_ring.ring_type == R_NAZREG)) /* good ring in use - saved from death */ { mvaddstr(4, 0, "Your ring saved you from death!\n"); refresh(); Player.p_ring.ring_type = R_NONE; Player.p_energy = Player.p_maxenergy / 12.0 + 1.0; if (Player.p_crowns > 0) --Player.p_crowns; return; } else if (Player.p_ring.ring_type == R_BAD || Player.p_ring.ring_type == R_SPOILED) /* bad ring in possession; name idiot after player */ { mvaddstr(4, 0, "Your ring has taken control of you and turned you into a monster!\n"); fseek(Monstfp, 13L * SZ_MONSTERSTRUCT, 0); fread((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp); strcpy(Curmonster.m_name, Player.p_name); fseek(Monstfp, 13L * SZ_MONSTERSTRUCT, 0); fwrite((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp); fflush(Monstfp); } } enterscore(); /* update score board */ /* put info in last dead file */ fp = fopen(_PATH_LASTDEAD, "w"); fprintf(fp,"%s (%s, run by %s, level %.0f, killed by %s)", Player.p_name, descrtype(&Player, TRUE), Player.p_login, Player.p_level, how); fclose(fp); /* let other players know */ fp = fopen(_PATH_MESS, "w"); fprintf(fp, "%s was killed by %s.", Player.p_name, how); fclose(fp); freerecord(&Player, Fileloc); clear(); move(10, 0); addstr(deathmesg[(int) ROLL(0.0, (double) sizeof(deathmesg) / sizeof(char *))]); addstr("Care to give it another try ? "); ch = getanswer("NY", FALSE); if (ch == 'Y') { cleanup(FALSE); execl(_PATH_GAMEPROG, "phantasia", "-s", (Wizard ? "-S": (char *) NULL), 0); exit(0); /*NOTREACHED*/ } cleanup(TRUE); /*NOTREACHED*/}/**//************************************************************************// FUNCTION NAME: writerecord()// FUNCTION: update structure in player file// AUTHOR: E. A. Estes, 12/4/85// ARGUMENTS:/ struct player *playerp - pointer to structure to write out/ long place - location in file to updata// RETURN VALUE: none// MODULES CALLED: fseek(), fwrite(), fflush()// GLOBAL INPUTS: *Playersfp// GLOBAL OUTPUTS: none// DESCRIPTION:/ Update location in player file with given structure.//************************************************************************/writerecord(playerp, place)register struct player *playerp;long place;{ fseek(Playersfp, place, 0); fwrite((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp); fflush(Playersfp);}/**//************************************************************************// FUNCTION NAME: explevel()// FUNCTION: calculate level based upon experience// AUTHOR: E. A. Estes, 12/4/85// ARGUMENTS:/ double experience - experience to calculate experience level from// RETURN VALUE: experience level// MODULES CALLED: pow(), floor()// GLOBAL INPUTS: none// GLOBAL OUTPUTS: none// DESCRIPTION: / Experience level is a geometric progression. This has been finely/ tuned over the years, and probably should not be changed.//************************************************************************/doubleexplevel(experience)double experience;{ if (experience < 1.1e7) return(floor(pow((experience / 1000.0), 0.4875))); else return(floor(pow((experience / 1250.0), 0.4865)));}/**//************************************************************************// FUNCTION NAME: truncstring()// FUNCTION: truncate trailing blanks off a string// AUTHOR: E. A. Estes, 12/4/85// ARGUMENTS: / char *string - pointer to null terminated string// RETURN VALUE: none// MODULES CALLED: strlen()// GLOBAL INPUTS: none// GLOBAL OUTPUTS: none// DESCRIPTION: / Put nul characters in place of spaces at the end of the string.//************************************************************************/truncstring(string)register char *string;{register int length; /* length of string */ length = strlen(string); while (string[--length] == ' ') string[length] = '\0';}/**//************************************************************************// FUNCTION NAME: altercoordinates()// FUNCTION: Alter x, y coordinates and set/check location flags// AUTHOR: E. A. Estes, 12/16/85// ARGUMENTS: / double xnew, ynew - new x, y coordinates/ int operation - operation to perform with coordinates// RETURN VALUE: none// MODULES CALLED: fabs(), floor(), drandom(), distance()// GLOBAL INPUTS: Circle, Beyond, Player// GLOBAL OUTPUTS: Marsh, Circle, Beyond, Throne, Player, Changed// DESCRIPTION: / This module is called whenever the player's coordinates are altered./ If the player is beyond the point of no return, he/she is forced/ to stay there.//************************************************************************/altercoordinates(xnew, ynew, operation)double xnew;double ynew;int operation;{ switch (operation) { case A_FORCED: /* move with no checks */ break; case A_NEAR: /* pick random coordinates near */ xnew = Player.p_x + ROLL(1.0, 5.0); ynew = Player.p_y - ROLL(1.0, 5.0); /* fall through for check */ case A_SPECIFIC: /* just move player */ if (Beyond && fabs(xnew) < D_BEYOND && fabs(ynew) < D_BEYOND) /* * cannot move back from point of no return * pick the largest coordinate to remain unchanged */ { if (fabs(xnew) > fabs(ynew)) xnew = SGN(Player.p_x) * MAX(fabs(Player.p_x), D_BEYOND); else ynew = SGN(Player.p_y) * MAX(fabs(Player.p_y), D_BEYOND); } break; case A_FAR: /* pick random coordinates far */ xnew = Player.p_x + SGN(Player.p_x) * ROLL(50 * Circle, 250 * Circle); ynew = Player.p_y + SGN(Player.p_y) * ROLL(50 * Circle, 250 * Circle); break; } /* now set location flags and adjust coordinates */ Circle = CIRCLE(Player.p_x = floor(xnew), Player.p_y = floor(ynew));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -