2 * @(#)main.c 3.27 (Berkeley) 6/15/81
4 * Rogue: Exploring the Dungeons of Doom
5 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
8 * See the file LICENSE.TXT for full copyright and licensing information.
21 int num_checks
; /* times we've gone over in checkout() */
22 WINDOW
*cw
; /* Window that the player sees */
23 WINDOW
*hw
; /* Used for the help command */
24 WINDOW
*mw
; /* Used to store mosnters */
26 main(argc
, argv
, envp
)
31 register struct linked_list
*item
;
32 register struct object
*obj
;
39 * check for print-score option
41 if (argc
== 2 && strcmp(argv
[1], "-s") == 0)
48 * Check to see if he is a wizard
50 if (argc
>= 2 && argv
[1][0] == '\0')
51 if (strcmp(PASSWD
, xcrypt(md_getpass("Wizard's password: "), "mT")) == 0)
59 * get home and options from environment
61 strncpy(home
, md_gethomedir(), PATH_MAX
);
63 strcpy(file_name
, home
);
64 strcat(file_name
, "rogue36.sav");
66 if ((env
= getenv("ROGUEOPTS")) != NULL
)
68 if (env
== NULL
|| whoami
[0] == '\0')
69 strucpy(whoami
, md_getusername(md_getuid()), strlen(md_getusername(md_getuid())));
70 if (env
== NULL
|| fruit
[0] == '\0')
71 strcpy(fruit
, "slime-mold");
73 if (too_much() && !wizard
&& !author())
75 printf("Sorry, %s, but the system is too loaded now.\n", whoami
);
76 printf("Try again later. Meanwhile, why not enjoy a%s %s?\n",
77 vowelstr(fruit
), fruit
);
82 if (!restore(argv
[1], envp
)) /* Note: restore will never return */
87 dnum
= (wizard
&& getenv("SEED") != NULL
?
88 atoi(getenv("SEED")) :
91 printf("Hello %s, welcome to dungeon #%d", whoami
, dnum
);
93 printf("Hello %s, just a moment while I dig the dungeon...", whoami
);
96 init_player(); /* Roll up the rogue */
97 init_things(); /* Set up probabilities of things */
98 init_names(); /* Set up names of scrolls */
99 init_colors(); /* Set up colors of potions */
100 init_stones(); /* Set up stone settings of rings */
101 init_materials(); /* Set up materials of wands */
102 initscr(); /* Start up cursor package */
107 printf("\n\nSorry, %s, but your terminal window has too few columns.\n", whoami
);
108 printf("Your terminal has %d columns, needs 70.\n",COLS
);
114 printf("\n\nSorry, %s, but your terminal window has too few lines.\n", whoami
);
115 printf("Your terminal has %d lines, needs 22.\n",LINES
);
124 cw
= newwin(LINES
, COLS
, 0, 0);
125 mw
= newwin(LINES
, COLS
, 0, 0);
126 hw
= newwin(LINES
, COLS
, 0, 0);
129 new_level(); /* Draw current level */
131 * Start up daemons and fuses
133 start_daemon(doctor
, 0, AFTER
);
134 fuse(swander
, 0, WANDERTIME
, AFTER
);
135 start_daemon(stomach
, 0, AFTER
);
136 start_daemon(runners
, 0, AFTER
);
138 * Give the rogue his weaponry. First a mace.
140 item
= new_item(sizeof *obj
);
141 obj
= (struct object
*) ldata(item
);
142 obj
->o_type
= WEAPON
;
144 init_weapon(obj
, MACE
);
147 obj
->o_flags
|= ISKNOW
;
148 add_pack(item
, TRUE
);
153 item
= new_item(sizeof *obj
);
154 obj
= (struct object
*) ldata(item
);
155 obj
->o_type
= WEAPON
;
157 init_weapon(obj
, BOW
);
160 obj
->o_flags
|= ISKNOW
;
161 add_pack(item
, TRUE
);
165 item
= new_item(sizeof *obj
);
166 obj
= (struct object
*) ldata(item
);
167 obj
->o_type
= WEAPON
;
168 obj
->o_which
= ARROW
;
169 init_weapon(obj
, ARROW
);
170 obj
->o_count
= 25+rnd(15);
171 obj
->o_hplus
= obj
->o_dplus
= 0;
172 obj
->o_flags
|= ISKNOW
;
173 add_pack(item
, TRUE
);
175 * And his suit of armor
177 item
= new_item(sizeof *obj
);
178 obj
= (struct object
*) ldata(item
);
180 obj
->o_which
= RING_MAIL
;
181 obj
->o_ac
= a_class
[RING_MAIL
] - 1;
182 obj
->o_flags
|= ISKNOW
;
184 add_pack(item
, TRUE
);
186 * Give him some food too
188 item
= new_item(sizeof *obj
);
189 obj
= (struct object
*) ldata(item
);
193 add_pack(item
, TRUE
);
199 * Exit the program abnormally.
205 fatal("Ok, if you want to exit that badly, I'll have to allow it\n");
210 * Exit the program, printing a message.
226 * Pick a very random number.
232 return range
== 0 ? 0 : abs(RN
) % range
;
237 * roll a number of dice
241 register int number
, sides
;
243 register int dtotal
= 0;
246 dtotal
+= rnd(sides
)+1;
250 * handle stop and start signals
257 signal(SIGTSTP
, SIG_IGN
);
259 mvcur(0, COLS
- 1, LINES
- 1, 0);
263 signal(SIGTSTP
, SIG_DFL
);
265 signal(SIGTSTP
, tstp
);
269 clearok(curscr
, TRUE
);
272 flush_type(); /* flush input */
278 signal(SIGHUP
, auto_save
);
280 signal(SIGILL
, auto_save
);
282 signal(SIGTRAP
, auto_save
);
285 signal(SIGIOT
, auto_save
);
288 signal(SIGEMT
, auto_save
);
290 signal(SIGFPE
, auto_save
);
292 signal(SIGBUS
, auto_save
);
294 signal(SIGSEGV
, auto_save
);
296 signal(SIGSYS
, auto_save
);
299 signal(SIGPIPE
, auto_save
);
301 signal(SIGTERM
, auto_save
);
302 signal(SIGINT
, quit
);
304 signal(SIGQUIT
, endit
);
307 signal(SIGTSTP
, tstp
);
313 signal(SIGALRM
, checkout
);
314 alarm(CHECKTIME
* 60);
319 crmode(); /* Cbreak mode */
320 noecho(); /* Echo off */
325 * The main loop of the program. Loop until the game is over,
326 * refreshing things and looking at the proper times.
334 * set up defaults for slow terminals
338 if (baudrate() < 1200)
345 * parse environment declaration of options
347 if ((opts
= getenv("ROGUEOPTS")) != NULL
)
352 oldrp
= roomin(&hero
);
354 command(); /* Command execution */
359 * see if the system is being used too much for this game
365 if (md_getloadavg(avec
) == 0)
366 return (avec
[2] > (MAXLOAD
/ 10.0));
368 return (md_ucount() > MAXUSERS
);
372 * see if a user is an author of the program
385 int chmsg(char *fmt
, ...);
390 static char *msgs
[] = {
391 "The load is too high to be playing. Please leave in %d minutes",
392 "Please save your game. You have %d minutes",
393 "Last warning. You have %d minutes to leave",
397 signal(SIGALRM
, checkout
);
402 fatal("Sorry. You took to long. You are dead\n");
403 checktime
= CHECKTIME
/ (num_checks
+ 1);
404 chmsg(msgs
[num_checks
++], checktime
);
406 alarm(checktime
* 60);
413 chmsg("The load has dropped back down. You have a reprieve.");
417 alarm(CHECKTIME
* 60);
423 * checkout()'s version of msg. If we are in the middle of a shell, do a
424 * printf instead of a msg to avoid the refresh.
426 chmsg(char *fmt
, ...)