xref: /dragonfly/games/hack/hack.u_init.c (revision ffe53622)
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.u_init.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.u_init.c,v 1.4 1999/11/16 02:57:13 billf Exp $ */
4 
5 #include "hack.h"
6 #define	Strcpy	strcpy
7 #define	Strcat	strcat
8 #define	UNDEF_TYP	0
9 #define	UNDEF_SPE	'\177'
10 
11 struct you zerou;
12 char pl_character[PL_CSIZ];
13 /*
14  * must all have distinct first letter
15  * roles[4] may be changed to -man
16  */
17 char roles[][12 + 1] = {
18 	"Tourist", "Speleologist", "Fighter", "Knight",
19 	"Cave-man", "Wizard"
20 };
21 #define	NR_OF_ROLES	SIZE(roles)
22 char rolesyms[NR_OF_ROLES + 1];		/* filled by u_init() */
23 
24 struct trobj {
25 	uchar trotyp;
26 	schar trspe;
27 	char trolet;
28 	Bitfield(trquan,6);
29 	Bitfield(trknown,1);
30 };
31 
32 #ifdef WIZARD
33 struct trobj Extra_objs[] = {
34 	{ 0, 0, 0, 0, 0 },
35 	{ 0, 0, 0, 0, 0 }
36 };
37 #endif /* WIZARD */
38 
39 struct trobj Cave_man[] = {
40 	{ MACE, 1, WEAPON_SYM, 1, 1 },
41 	{ BOW, 1, WEAPON_SYM, 1, 1 },
42 	{ ARROW, 0, WEAPON_SYM, 25, 1 },	/* quan is variable */
43 	{ LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1 },
44 	{ 0, 0, 0, 0, 0}
45 };
46 
47 struct trobj Fighter[] = {
48 	{ TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1 },
49 	{ RING_MAIL, 0, ARMOR_SYM, 1, 1 },
50 	{ 0, 0, 0, 0, 0 }
51 };
52 
53 struct trobj Knight[] = {
54 	{ LONG_SWORD, 0, WEAPON_SYM, 1, 1 },
55 	{ SPEAR, 2, WEAPON_SYM, 1, 1 },
56 	{ RING_MAIL, 1, ARMOR_SYM, 1, 1 },
57 	{ HELMET, 0, ARMOR_SYM, 1, 1 },
58 	{ SHIELD, 0, ARMOR_SYM, 1, 1 },
59 	{ PAIR_OF_GLOVES, 0, ARMOR_SYM, 1, 1 },
60 	{ 0, 0, 0, 0, 0 }
61 };
62 
63 struct trobj Speleologist[] = {
64 	{ STUDDED_LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1 },
65 	{ UNDEF_TYP, 0, POTION_SYM, 2, 0 },
66 	{ FOOD_RATION, 0, FOOD_SYM, 3, 1 },
67 	{ PICK_AXE, UNDEF_SPE, TOOL_SYM, 1, 0 },
68 	{ ICE_BOX, 0, TOOL_SYM, 1, 0 },
69 	{ 0, 0, 0, 0, 0}
70 };
71 
72 struct trobj Tinopener[] = {
73 	{ CAN_OPENER, 0, TOOL_SYM, 1, 1 },
74 	{ 0, 0, 0, 0, 0 }
75 };
76 
77 struct trobj Tourist[] = {
78 	{ UNDEF_TYP, 0, FOOD_SYM, 10, 1 },
79 	{ POT_EXTRA_HEALING, 0, POTION_SYM, 2, 0 },
80 	{ EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1 },
81 	{ DART, 2, WEAPON_SYM, 25, 1 },	/* quan is variable */
82 	{ 0, 0, 0, 0, 0 }
83 };
84 
85 struct trobj Wizard[] = {
86 	{ ELVEN_CLOAK, 0, ARMOR_SYM, 1, 1 },
87 	{ UNDEF_TYP, UNDEF_SPE, WAND_SYM, 2, 0 },
88 	{ UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 0 },
89 	{ UNDEF_TYP, UNDEF_SPE, POTION_SYM, 2, 0 },
90 	{ UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 0 },
91 	{ 0, 0, 0, 0, 0 }
92 };
93 
94 static void ini_inv(struct trobj *);
95 #ifdef WIZARD
96 static void wiz_inv(void);
97 #endif
98 static int role_index(char);
99 
100 void
101 u_init(void)
102 {
103 	int i;
104 	char exper = 'y', pc;
105 
106 	if (flags.female)	/* should have been set in HACKOPTIONS */
107 		strlcpy(roles[4], "Cave-woman", sizeof(roles[4]));
108 	for (i = 0; i < NR_OF_ROLES; i++)
109 		rolesyms[i] = roles[i][0];
110 	rolesyms[i] = 0;
111 
112 	if ((pc = pl_character[0]) != '\0') {
113 		if ('a' <= pc && pc <= 'z')
114 			pc += 'A' - 'a';
115 		if ((i = role_index(pc)) >= 0)
116 			goto got_suffix;	/* implies experienced */
117 		printf("\nUnknown role: %c\n", pc);
118 		pl_character[0] = pc = 0;
119 	}
120 
121 	printf("\nAre you an experienced player? [ny] ");
122 
123 	while (!strchr("ynYN \n\004", (exper = readchar())))
124 		bell();
125 	if (exper == '\004')	/* Give him an opportunity to get out */
126 		end_of_input();
127 	printf("%c\n", exper);	/* echo */
128 	if (strchr("Nn \n", exper)) {
129 		exper = 0;
130 		goto beginner;
131 	}
132 
133 	printf("\nTell me what kind of character you are:\n");
134 	printf("Are you");
135 	for (i = 0; i < NR_OF_ROLES; i++) {
136 		printf(" a %s", roles[i]);
137 		if (i == 2)	/* %% */
138 			printf(",\n\t");
139 		else if (i < NR_OF_ROLES - 2)
140 			printf(",");
141 		else if (i == NR_OF_ROLES - 2)
142 			printf(" or");
143 	}
144 	printf("? [%s] ", rolesyms);
145 
146 	while ((pc = readchar()) != '\0') {
147 		if ('a' <= pc && pc <= 'z')
148 			pc += 'A' - 'a';
149 		if ((i = role_index(pc)) >= 0) {
150 			printf("%c\n", pc);	/* echo */
151 			fflush(stdout);		/* should be seen */
152 			break;
153 		}
154 		if (pc == '\n')
155 			break;
156 		if (pc == '\004')	/* Give him the opportunity to get out */
157 			end_of_input();
158 		bell();
159 	}
160 	if (pc == '\n')
161 		pc = 0;
162 
163 beginner:
164 	if (!pc) {
165 		printf("\nI'll choose a character for you.\n");
166 		i = rn2(NR_OF_ROLES);
167 		pc = rolesyms[i];
168 		printf("This game you will be a%s %s.\n",
169 		       exper ? "n experienced" : "",
170 		       roles[i]);
171 		getret();
172 		/* give him some feedback in case mklev takes much time */
173 		putchar('\n');
174 		fflush(stdout);
175 	}
176 	if (exper)
177 		roles[i][0] = pc;
178 
179 got_suffix:
180 
181 	strncpy(pl_character, roles[i], PL_CSIZ - 1);
182 	pl_character[PL_CSIZ - 1] = 0;
183 	flags.beginner = 1;
184 	u = zerou;
185 	u.usym = '@';
186 	u.ulevel = 1;
187 	init_uhunger();
188 #ifdef QUEST
189 	u.uhorizon = 6;
190 #endif /* QUEST */
191 	uarm = uarm2 = uarmh = uarms = uarmg = uwep = uball = uchain =
192 		uleft = uright = 0;
193 
194 	switch (pc) {
195 	case 'c':
196 	case 'C':
197 		Cave_man[2].trquan = 12 + rnd(9) * rnd(9);
198 		u.uhp = u.uhpmax = 16;
199 		u.ustr = u.ustrmax = 18;
200 		ini_inv(Cave_man);
201 		break;
202 	case 't':
203 	case 'T':
204 		Tourist[3].trquan = 20 + rnd(20);
205 		u.ugold = u.ugold0 = rnd(1000);
206 		u.uhp = u.uhpmax = 10;
207 		u.ustr = u.ustrmax = 8;
208 		ini_inv(Tourist);
209 		if (!rn2(25))
210 			ini_inv(Tinopener);
211 		break;
212 	case 'w':
213 	case 'W':
214 		for (i = 1; i <= 4; i++)
215 			if (!rn2(5))
216 				Wizard[i].trquan += rn2(3) - 1;
217 		u.uhp = u.uhpmax = 15;
218 		u.ustr = u.ustrmax = 16;
219 		ini_inv(Wizard);
220 		break;
221 	case 's':
222 	case 'S':
223 		Fast = INTRINSIC;
224 		Stealth = INTRINSIC;
225 		u.uhp = u.uhpmax = 12;
226 		u.ustr = u.ustrmax = 10;
227 		ini_inv(Speleologist);
228 		if (!rn2(10))
229 			ini_inv(Tinopener);
230 		break;
231 	case 'k':
232 	case 'K':
233 		u.uhp = u.uhpmax = 12;
234 		u.ustr = u.ustrmax = 10;
235 		ini_inv(Knight);
236 		break;
237 	case 'f':
238 	case 'F':
239 		u.uhp = u.uhpmax = 14;
240 		u.ustr = u.ustrmax = 17;
241 		ini_inv(Fighter);
242 		break;
243 	default:		/* impossible */
244 		u.uhp = u.uhpmax = 12;
245 		u.ustr = u.ustrmax = 16;
246 	}
247 	find_ac();
248 	if (!rn2(20)) {
249 		int d1 = rn2(7) - 2;	/* biased variation */
250 		u.ustr += d1;
251 		u.ustrmax += d1;
252 	}
253 
254 #ifdef WIZARD
255 	if (wizard)
256 		wiz_inv();
257 #endif /* WIZARD */
258 
259 	/* make sure he can carry all he has - especially for T's */
260 	while (inv_weight() > 0 && u.ustr < 118)
261 		u.ustr++, u.ustrmax++;
262 }
263 
264 static void
265 ini_inv(struct trobj *trop)
266 {
267 	struct obj *obj;
268 
269 	while (trop->trolet) {
270 		obj = mkobj(trop->trolet);
271 		obj->known = trop->trknown;
272 		/* not obj->dknown = 1; - let him look at it at least once */
273 		obj->cursed = 0;
274 		if (obj->olet == WEAPON_SYM) {
275 			obj->quan = trop->trquan;
276 			trop->trquan = 1;
277 		}
278 		if (trop->trspe != UNDEF_SPE)
279 			obj->spe = trop->trspe;
280 		if (trop->trotyp != UNDEF_TYP)
281 			obj->otyp = trop->trotyp;
282 		else if (obj->otyp == WAN_WISHING)	/* gitpyr!robert */
283 			obj->otyp = WAN_DEATH;
284 		obj->owt = weight(obj);	/* defined after setting otyp+quan */
285 		obj = addinv(obj);
286 		if (obj->olet == ARMOR_SYM) {
287 			switch (obj->otyp) {
288 			case SHIELD:
289 				if (!uarms)
290 					setworn(obj, W_ARMS);
291 				break;
292 			case HELMET:
293 				if (!uarmh)
294 					setworn(obj, W_ARMH);
295 				break;
296 			case PAIR_OF_GLOVES:
297 				if (!uarmg)
298 					setworn(obj, W_ARMG);
299 				break;
300 			case ELVEN_CLOAK:
301 				if (!uarm2)
302 					setworn(obj, W_ARM);
303 				break;
304 			default:
305 				if (!uarm)
306 					setworn(obj, W_ARM);
307 			}
308 		}
309 		if (obj->olet == WEAPON_SYM)
310 			if (!uwep)
311 				setuwep(obj);
312 #ifndef PYRAMID_BUG
313 		if (--trop->trquan)	/* make a similar object */
314 			continue;
315 #else
316 		if (trop->trquan) {	/* check if zero first */
317 			--trop->trquan;
318 			if (trop->trquan)
319 				continue;	/* make a similar object */
320 		}
321 #endif /* PYRAMID_BUG */
322 		trop++;
323 	}
324 }
325 
326 #ifdef WIZARD
327 static void
328 wiz_inv(void)
329 {
330 	struct trobj *trop = &Extra_objs[0];
331 	char *ep = getenv("INVENT");
332 	int type;
333 
334 	while (ep && *ep) {
335 		type = atoi(ep);
336 		ep = strchr(ep, ',');
337 		if (ep)
338 			while (*ep == ',' || *ep == ' ')
339 				ep++;
340 		if (type <= 0 || type > NROFOBJECTS)
341 			continue;
342 		trop->trotyp = type;
343 		trop->trolet = objects[type].oc_olet;
344 		trop->trspe = 4;
345 		trop->trknown = 1;
346 		trop->trquan = 1;
347 		ini_inv(trop);
348 	}
349 	/* give him a wand of wishing by default */
350 	trop->trotyp = WAN_WISHING;
351 	trop->trolet = WAND_SYM;
352 	trop->trspe = 20;
353 	trop->trknown = 1;
354 	trop->trquan = 1;
355 	ini_inv(trop);
356 }
357 #endif /* WIZARD */
358 
359 void
360 plnamesuffix(void)
361 {
362 	char *p;
363 
364 	if ((p = strrchr(plname, '-')) != NULL) {
365 		*p = 0;
366 		pl_character[0] = p[1];
367 		pl_character[1] = 0;
368 		if (!plname[0]) {
369 			askname();
370 			plnamesuffix();
371 		}
372 	}
373 }
374 
375 static int
376 role_index(char pc)
377 {               /* must be called only from u_init() */
378 		/* so that rolesyms[] is defined */
379 	char *cp;
380 
381 	if ((cp = strchr(rolesyms, pc)) != NULL)
382 		return (cp - rolesyms);
383 	return (-1);
384 }
385