📄 main.c
字号:
/* main.c */#include <sys/types.h>#include "header.h"#include <pwd.h>static char copyright[]="\nLarn is copyrighted 1986 by Noah Morgan.\n";int srcount=0; /* line counter for showstr() */int dropflag=0; /* if 1 then don't lookforobject() next round */int rmst=80; /* random monster creation counter */int userid; /* the players login user id number */char nowelcome=0,nomove=0; /* if (nomove) then don't count next iteration as a move */static char viewflag=0; /* if viewflag then we have done a 99 stay here and don't showcell in the main loop */char restorflag=0; /* 1 means restore has been done */static char cmdhelp[] = "\Cmd line format: larn [-slicnh] [-o<optsifle>] [-##] [++]\n\ -s show the scoreboard\n\ -l show the logfile (wizard id only)\n\ -i show scoreboard with inventories of dead characters\n\ -c create new scoreboard (wizard id only)\n\ -n suppress welcome message on starting game\n\ -## specify level of difficulty (example: -5)\n\ -h print this help text\n\ ++ restore game from checkpoint file\n\ -o<optsfile> specify .larnopts filename to be used instead of \"~/.larnopts\"\n\";#ifdef VT100static char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125", "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340", "vt341" };#endif VT100/* ************ MAIN PROGRAM ************ */main(argc,argv) int argc; char **argv; { register int i,j; int hard; char *ptr=0,*ttype; struct passwd *pwe;/* * first task is to identify the player */#ifndef VT100 init_term(); /* setup the terminal (find out what type) for termcap */#endif VT100 if (((ptr = getlogin()) == 0) || (*ptr==0)) /* try to get login name */ if (pwe=getpwuid(getuid())) /* can we get it from /etc/passwd? */ ptr = pwe->pw_name; else if ((ptr = getenv("USER")) == 0) if ((ptr = getenv("LOGNAME")) == 0) { noone: write(2, "Can't find your logname. Who Are You?\n",39); exit(); } if (ptr==0) goto noone; if (strlen(ptr)==0) goto noone;/* * second task is to prepare the pathnames the player will need */ strcpy(loginname,ptr); /* save loginname of the user for logging purposes */ strcpy(logname,ptr); /* this will be overwritten with the players name */ if ((ptr = getenv("HOME")) == 0) ptr = "."; strcpy(savefilename, ptr); strcat(savefilename, "/Larn.sav"); /* save file name in home directory */ sprintf(optsfile, "%s/.larnopts",ptr); /* the .larnopts filename *//* * now malloc the memory for the dungeon */ cell = (struct cel *)malloc(sizeof(struct cel)*(MAXLEVEL+MAXVLEVEL)*MAXX*MAXY); if (cell == 0) died(-285); /* malloc failure */ lpbuf = malloc((5* BUFBIG)>>2); /* output buffer */ inbuffer = malloc((5*MAXIBUF)>>2); /* output buffer */ if ((lpbuf==0) || (inbuffer==0)) died(-285); /* malloc() failure */ lcreat((char*)0); newgame(); /* set the initial clock */ hard= -1;#ifdef VT100/* * check terminal type to avoid users who have not vt100 type terminals */ ttype = getenv("TERM"); for (j=1, i=0; i<sizeof(termtypes)/sizeof(char *); i++) if (strcmp(ttype,termtypes[i]) == 0) { j=0; break; } if (j) { lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n"); lflush(); exit(); }#endif VT100/* * now make scoreboard if it is not there (don't clear) */ if (access(scorefile,0) == -1) /* not there */ makeboard();/* * now process the command line arguments */ for (i=1; i<argc; i++) { if (argv[i][0] == '-') switch(argv[i][1]) { case 's': showscores(); exit(); /* show scoreboard */ case 'l': /* show log file */ diedlog(); exit(); case 'i': showallscores(); exit(); /* show all scoreboard */ case 'c': /* anyone with password can create scoreboard */ lprcat("Preparing to initialize the scoreboard.\n"); if (getpassword() != 0) /*make new scoreboard*/ { makeboard(); lprc('\n'); showscores(); } exit(); case 'n': /* no welcome msg */ nowelcome=1; argv[i][0]=0; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* for hardness */ sscanf(&argv[i][1],"%d",&hard); break; case 'h': /* print out command line arguments */ write(1,cmdhelp,sizeof(cmdhelp)); exit(); case 'o': /* specify a .larnopts filename */ strncpy(optsfile,argv[i]+2,127); break; default: printf("Unknown option <%s>\n",argv[i]); exit(); }; if (argv[i][0] == '+') { clear(); restorflag = 1; if (argv[i][1] == '+') { hitflag=1; restoregame(ckpfile); /* restore checkpointed game */ } i = argc; } } readopts(); /* read the options file if there is one */#ifdef UIDSCORE userid = geteuid(); /* obtain the user's effective id number */#else UIDSCORE userid = getplid(logname); /* obtain the players id number */#endif UIDSCORE if (userid < 0) { write(2,"Can't obtain playerid\n",22); exit(); }#ifdef HIDEBYLINK/* * this section of code causes the program to look like something else to ps */ if (strcmp(psname,argv[0])) /* if a different process name only */ { if ((i=access(psname,1)) < 0) { /* link not there */ if (link(argv[0],psname)>=0) { argv[0] = psname; execv(psname,argv); } } else unlink(psname); } for (i=1; i<argc; i++) { szero(argv[i]); /* zero the argument to avoid ps snooping */ }#endif HIDEBYLINK if (access(savefilename,0)==0) /* restore game if need to */ { clear(); restorflag = 1; hitflag=1; restoregame(savefilename); /* restore last game */ } sigsetup(); /* trap all needed signals */ sethard(hard); /* set up the desired difficulty */ setupvt100(); /* setup the terminal special mode */ if (c[HP]==0) /* create new game */ { makeplayer(); /* make the character that will play */ newcavelevel(0);/* make the dungeon */ predostuff = 1; /* tell signals that we are in the welcome screen */ if (nowelcome==0) welcome(); /* welcome the player to the game */ } drawscreen(); /* show the initial dungeon */ predostuff = 2; /* tell the trap functions that they must do a showplayer() from here on */ /* nice(1); /* games should be run niced */ yrepcount = hit2flag = 0; while (1) { if (dropflag==0) lookforobject(); /* see if there is an object here */ else dropflag=0; /* don't show it just dropped an item */ if (hitflag==0) { if (c[HASTEMONST]) movemonst(); movemonst(); } /* move the monsters */ if (viewflag==0) showcell(playerx,playery); else viewflag=0; /* show stuff around player */ if (hit3flag) flushall(); hitflag=hit3flag=0; nomove=1; bot_linex(); /* update bottom line */ while (nomove) { if (hit3flag) flushall(); nomove=0; parse(); } /* get commands and make moves */ regen(); /* regenerate hp and spells */ if (c[TIMESTOP]==0) if (--rmst <= 0) { rmst = 120-(level<<2); fillmonst(makemonst(level)); } } }/* showstr() show character's inventory */showstr() { register int i,number; for (number=3, i=0; i<26; i++) if (iven[i]) number++; /* count items in inventory */ t_setup(number); qshowstr(); t_endup(number); }qshowstr() { register int i,j,k,sigsav; srcount=0; sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ if (c[GOLD]) { lprintf(".) %d gold pieces",(long)c[GOLD]); srcount++; } for (k=26; k>=0; k--) if (iven[k]) { for (i=22; i<84; i++) for (j=0; j<=k; j++) if (i==iven[j]) show3(j); k=0; } lprintf("\nElapsed time is %d. You have %d mobuls left",(long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100)); more(); nosignal=sigsav; }/* * subroutine to clear screen depending on # lines to display */t_setup(count) register int count; { if (count<20) /* how do we clear the screen? */ { cl_up(79,count); cursor(1,1); } else { resetscroll(); clear(); } }/* * subroutine to restore normal display screen depending on t_setup() */t_endup(count) register int count; { if (count<18) /* how did we clear the screen? */ draws(0,MAXX,0,(count>MAXY) ? MAXY : count); else { drawscreen(); setscroll(); } }/* function to show the things player is wearing only */showwear() { register int i,j,sigsav,count; sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ srcount=0; for (count=2,j=0; j<=26; j++) /* count number of items we will display */ if (i=iven[j]) switch(i) { case OLEATHER: case OPLATE: case OCHAIN: case ORING: case OSTUDLEATHER: case OSPLINT: case OPLATEARMOR: case OSSPLATE: case OSHIELD: count++; }; t_setup(count); for (i=22; i<84; i++) for (j=0; j<=26; j++) if (i==iven[j]) switch(i) { case OLEATHER: case OPLATE: case OCHAIN: case ORING: case OSTUDLEATHER: case OSPLINT: case OPLATEARMOR: case OSSPLATE: case OSHIELD: show3(j); }; more(); nosignal=sigsav; t_endup(count); }/* function to show the things player can wield only */showwield() { register int i,j,sigsav,count; sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ srcount=0; for (count=2,j=0; j<=26; j++) /* count how many items */ if (i=iven[j]) switch(i) { case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE: case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT: case OSPIRITSCARAB: case OCUBEofUNDEAD: case OPOTION: case OSCROLL: break; default: count++; }; t_setup(count); for (i=22; i<84; i++) for (j=0; j<=26; j++) if (i==iven[j]) switch(i) { case ODIAMOND: case ORUBY: case OEMERALD: case OSAPPHIRE: case OBOOK: case OCHEST: case OLARNEYE: case ONOTHEFT: case OSPIRITSCARAB: case OCUBEofUNDEAD: case OPOTION: case OSCROLL: break; default: show3(j); }; more(); nosignal=sigsav; t_endup(count); }/* * function to show the things player can read only */showread() { register int i,j,sigsav,count; sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ srcount=0; for (count=2,j=0; j<=26; j++) switch(iven[j]) { case OBOOK: case OSCROLL: count++; }; t_setup(count); for (i=22; i<84; i++) for (j=0; j<=26; j++) if (i==iven[j]) switch(i) { case OBOOK: case OSCROLL: show3(j); }; more(); nosignal=sigsav; t_endup(count); }/* * function to show the things player can eat only */showeat() { register int i,j,sigsav,count; sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ srcount=0; for (count=2,j=0; j<=26; j++) switch(iven[j]) { case OCOOKIE: count++; }; t_setup(count); for (i=22; i<84; i++) for (j=0; j<=26; j++) if (i==iven[j]) switch(i) { case OCOOKIE: show3(j); }; more(); nosignal=sigsav; t_endup(count); }/* function to show the things player can quaff only */showquaff() { register int i,j,sigsav,count; sigsav=nosignal; nosignal=1; /* don't allow ^c etc */ srcount=0; for (count=2,j=0; j<=26; j++) switch(iven[j]) { case OPOTION: count++; }; t_setup(count); for (i=22; i<84; i++) for (j=0; j<=26; j++) if (i==iven[j]) switch(i) { case OPOTION: show3(j); }; more(); nosignal=sigsav; t_endup(count); }show1(idx,str2) register int idx; register char *str2[]; { if (str2==0) lprintf("\n%c) %s",idx+'a',objectname[iven[idx]]); else if (*str2[ivenarg[idx]]==0) lprintf("\n%c) %s",idx+'a',objectname[iven[idx]]); else lprintf("\n%c) %s of%s",idx+'a',objectname[iven[idx]],str2[ivenarg[idx]]); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -