xref: /dragonfly/games/rogue/init.c (revision 3170ffd7)
1 /*-
2  * Copyright (c) 1988, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Timothy C. Stoehr.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * @(#)init.c	8.1 (Berkeley) 5/31/93
33  * $FreeBSD: src/games/rogue/init.c,v 1.4 1999/11/30 03:49:22 billf Exp $
34  * $DragonFly: src/games/rogue/init.c,v 1.3 2006/09/02 19:31:07 pavalos Exp $
35  */
36 
37 /*
38  * init.c
39  *
40  * This source herein may be modified and/or distributed by anybody who
41  * so desires, with the following restrictions:
42  *    1.)  No portion of this notice shall be removed.
43  *    2.)  Credit shall not be taken for the creation of this source.
44  *    3.)  This code is not to be traded, sold, or used for personal
45  *         gain or profit.
46  *
47  */
48 
49 #include <stdio.h>
50 #include "rogue.h"
51 
52 static void do_args(int, char **);
53 static void do_opts(void);
54 static void env_get_value(char **, char *, boolean);
55 static void init_str(char **, const char *);
56 static void player_init(void);
57 
58 
59 char login_name[MAX_OPT_LEN];
60 char *nick_name = NULL;
61 char *rest_file = NULL;
62 boolean cant_int = 0;
63 boolean did_int = 0;
64 boolean score_only;
65 boolean init_curses = 0;
66 boolean save_is_interactive = 1;
67 boolean ask_quit = 1;
68 boolean no_skull = 0;
69 boolean passgo = 0;
70 boolean flush = 1;
71 const char *error_file = "rogue.esave";
72 const char *byebye_string = "Okay, bye bye!";
73 
74 extern char *fruit;
75 extern char *save_file;
76 extern short party_room;
77 extern boolean jump;
78 
79 boolean
80 init(int argc, char *argv[])
81 {
82 	const char *pn;
83 
84 	pn = md_gln();
85 	if ((!pn) || (strlen(pn) >= MAX_OPT_LEN)) {
86 		clean_up("Hey!  Who are you?");
87 	}
88 	strcpy(login_name, pn);
89 
90 	do_args(argc, argv);
91 	do_opts();
92 
93 	if (!score_only && !rest_file) {
94 		printf("Hello %s, just a moment while I dig the dungeon...",
95 			nick_name);
96 		fflush(stdout);
97 	}
98 
99 	initscr();
100 	if ((LINES < DROWS) || (COLS < DCOLS)) {
101 		clean_up("must be played on 24 x 80 screen");
102 	}
103 	start_window();
104 	init_curses = 1;
105 
106 	md_heed_signals();
107 
108 	if (score_only) {
109 		put_scores(NULL, 0);
110 	}
111 	srandomdev();
112 	if (rest_file) {
113 		restore(rest_file);
114 		return(1);
115 	}
116 	mix_colors();
117 	get_wand_and_ring_materials();
118 	make_scroll_titles();
119 
120 	level_objects.next_object = NULL;
121 	level_monsters.next_monster = NULL;
122 	player_init();
123 	ring_stats(0);
124 	return(0);
125 }
126 
127 static void
128 player_init(void)
129 {
130 	object *obj;
131 
132 	rogue.pack.next_object = NULL;
133 
134 	obj = alloc_object();
135 	get_food(obj, 1);
136 	add_to_pack(obj, &rogue.pack, 1);
137 
138 	obj = alloc_object();		/* initial armor */
139 	obj->what_is = ARMOR;
140 	obj->which_kind = RINGMAIL;
141 	obj->class = RINGMAIL+2;
142 	obj->is_protected = 0;
143 	obj->d_enchant = 1;
144 	add_to_pack(obj, &rogue.pack, 1);
145 	do_wear(obj);
146 
147 	obj = alloc_object();		/* initial weapons */
148 	obj->what_is = WEAPON;
149 	obj->which_kind = MACE;
150 	obj->damage = "2d3";
151 	obj->hit_enchant = obj->d_enchant = 1;
152 	obj->identified = 1;
153 	add_to_pack(obj, &rogue.pack, 1);
154 	do_wield(obj);
155 
156 	obj = alloc_object();
157 	obj->what_is = WEAPON;
158 	obj->which_kind = BOW;
159 	obj->damage = "1d2";
160 	obj->hit_enchant = 1;
161 	obj->d_enchant = 0;
162 	obj->identified = 1;
163 	add_to_pack(obj, &rogue.pack, 1);
164 
165 	obj = alloc_object();
166 	obj->what_is = WEAPON;
167 	obj->which_kind = ARROW;
168 	obj->quantity = get_rand(25, 35);
169 	obj->damage = "1d2";
170 	obj->hit_enchant = 0;
171 	obj->d_enchant = 0;
172 	obj->identified = 1;
173 	add_to_pack(obj, &rogue.pack, 1);
174 }
175 
176 void
177 clean_up(const char *estr)
178 {
179 	if (save_is_interactive) {
180 		if (init_curses) {
181 			move(DROWS-1, 0);
182 			refresh();
183 			stop_window();
184 		}
185 		printf("\n%s\n", estr);
186 	}
187 	md_exit(0);
188 }
189 
190 void
191 start_window(void)
192 {
193 	cbreak();
194 	noecho();
195 #ifndef BAD_NONL
196 	nonl();
197 #endif
198 	md_control_keybord(0);
199 }
200 
201 void
202 stop_window(void)
203 {
204 	endwin();
205 	md_control_keybord(1);
206 }
207 
208 void
209 byebye(void)
210 {
211 	md_ignore_signals();
212 	if (ask_quit) {
213 		quit(1);
214 	} else {
215 		clean_up(byebye_string);
216 	}
217 	md_heed_signals();
218 }
219 
220 void
221 onintr(void)
222 {
223 	md_ignore_signals();
224 	if (cant_int) {
225 		did_int = 1;
226 	} else {
227 		check_message();
228 		message("interrupt", 1);
229 	}
230 	md_heed_signals();
231 }
232 
233 void
234 error_save(void)
235 {
236 	save_is_interactive = 0;
237 	save_into_file(error_file);
238 	clean_up("");
239 }
240 
241 static void
242 do_args(int argc, char *argv[])
243 {
244 	short i, j;
245 
246 	for (i = 1; i < argc; i++) {
247 		if (argv[i][0] == '-') {
248 			for (j = 1; argv[i][j]; j++) {
249 				switch(argv[i][j]) {
250 				case 's':
251 					score_only = 1;
252 					break;
253 				}
254 			}
255 		} else {
256 			rest_file = argv[i];
257 		}
258 	}
259 }
260 
261 static void
262 do_opts(void)
263 {
264 	char *eptr;
265 
266 	if ((eptr = md_getenv("ROGUEOPTS")) != NULL) {
267 		for (;;) {
268 			while ((*eptr) == ' ') {
269 				eptr++;
270 			}
271 			if (!(*eptr)) {
272 				break;
273 			}
274 			if (!strncmp(eptr, "fruit=", 6)) {
275 				eptr += 6;
276 				env_get_value(&fruit, eptr, 1);
277 			} else if (!strncmp(eptr, "file=", 5)) {
278 				eptr += 5;
279 				env_get_value(&save_file, eptr, 0);
280 			} else if (!strncmp(eptr, "jump", 4)) {
281 				jump = 1;
282 			} else if (!strncmp(eptr, "name=", 5)) {
283 				eptr += 5;
284 				env_get_value(&nick_name, eptr, 0);
285 			} else if (!strncmp(eptr, "noaskquit", 9)) {
286 				ask_quit = 0;
287 			} else if (!strncmp(eptr, "noskull", 7) ||
288 					!strncmp(eptr,"notomb", 6)) {
289 				no_skull = 1;
290 			} else if (!strncmp(eptr, "passgo", 6)) {
291 				passgo = 1;
292 			} else if (!strncmp(eptr, "noflush", 7)) {
293 				flush = 0;
294 			}
295 			while ((*eptr) && (*eptr != ',')) {
296 				eptr++;
297 			}
298 			if (!(*(eptr++))) {
299 				break;
300 			}
301 		}
302 	}
303 	/* If some strings have not been set through ROGUEOPTS, assign defaults
304 	 * to them so that the options editor has data to work with.
305 	 */
306 	init_str(&nick_name, login_name);
307 	init_str(&save_file, "rogue.save");
308 	init_str(&fruit, "slime-mold");
309 }
310 
311 static void
312 env_get_value(char **s, char *e, boolean add_blank)
313 {
314 	short i = 0;
315 	const char *t;
316 
317 	t = e;
318 
319 	while ((*e) && (*e != ',')) {
320 		if (*e == ':') {
321 			*e = ';';		/* ':' reserved for score file purposes */
322 		}
323 		e++;
324 		if (++i >= MAX_OPT_LEN) {
325 			break;
326 		}
327 	}
328 	/* note: edit_opts() in room.c depends on this being the right size */
329 	*s = md_malloc(MAX_OPT_LEN + 2);
330 	strncpy(*s, t, i);
331 	if (add_blank) {
332 		(*s)[i++] = ' ';
333 	}
334 	(*s)[i] = '\0';
335 }
336 
337 static void
338 init_str(char **str, const char *dflt)
339 {
340 	if (!(*str)) {
341 		/* note: edit_opts() in room.c depends on this size */
342 		*str = md_malloc(MAX_OPT_LEN + 2);
343 		strcpy(*str, dflt);
344 	}
345 }
346