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