Source:NetHack 1.3d/u init.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to u_init.c from the source code of NetHack 1.3d.

Warning! This is the source code from an old release. For newer releases, see Source code

Screenshots and source code from Hack are used under the CWI license.

1.    /*	SCCS Id: @(#)u_init.c	1.3	87/07/14
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* u_init.c - version 1.0.3   */
4.    
5.    #include <stdio.h>
6.    #include <signal.h>
7.    #include "hack.h"
8.    #define Strcpy	(void) strcpy
9.    #define	Strcat	(void) strcat
10.   #define	UNDEF_TYP	0
11.   #define	UNDEF_SPE	'\177'
12.   extern struct obj *addinv();
13.   extern char *eos();
14.   extern char plname[];
15.   
16.   struct you zerou;
17.   char pl_character[PL_CSIZ];
18.   char *(roles[]) = {	/* must all have distinct first letter */
19.   			/* roles[4] & [7] may be changed for females */
20.   	"Archeologist", "Tourist", "Fighter", "Knight", "Cave-man",
21.   #ifdef NEWCLASS
22.   	"Samurai", "Ninja", "Priest",
23.   #endif
24.   #ifdef KAA
25.   	"Valkyrie", "Elf", "Healer",
26.   #endif
27.   	"Wizard"
28.   };
29.   #define	NR_OF_ROLES	SIZE(roles)
30.   char rolesyms[NR_OF_ROLES + 1];		/* filled by u_init() */
31.   
32.   struct trobj {
33.   	uchar trotyp;
34.   	schar trspe;
35.   	char trolet;
36.   	Bitfield(trquan,6);
37.   	Bitfield(trknown,1);
38.   };
39.   
40.   #ifdef WIZARD
41.   struct trobj Extra_objs[] = {
42.   	{ 0, 0, 0, 0, 0 },
43.   	{ 0, 0, 0, 0, 0 }
44.   };
45.   #endif
46.   
47.   struct trobj Cave_man[] = {
48.   #ifdef KAA
49.   	{ CLUB, 1, WEAPON_SYM, 1, 1 },
50.   #else
51.   	{ MACE, 1, WEAPON_SYM, 1, 1 },
52.   #endif
53.   	{ BOW, 1, WEAPON_SYM, 1, 1 },
54.   	{ ARROW, 0, WEAPON_SYM, 25, 1 },	/* quan is variable */
55.   	{ LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1 },
56.   	{ 0, 0, 0, 0, 0}
57.   };
58.   
59.   struct trobj Fighter[] = {
60.   	{ TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1 },
61.   	{ RING_MAIL, 0, ARMOR_SYM, 1, 1 },
62.   	{ 0, 0, 0, 0, 0 }
63.   };
64.   
65.   struct trobj Knight[] = {
66.   	{ LONG_SWORD, 0, WEAPON_SYM, 1, 1 },
67.   	{ SPEAR, 2, WEAPON_SYM, 1, 1 },
68.   	{ RING_MAIL, 1, ARMOR_SYM, 1, 1 },
69.   	{ HELMET, 0, ARMOR_SYM, 1, 1 },
70.   	{ SHIELD, 0, ARMOR_SYM, 1, 1 },
71.   	{ PAIR_OF_GLOVES, 0, ARMOR_SYM, 1, 1 },
72.   	{ 0, 0, 0, 0, 0 }
73.   };
74.   
75.   #ifdef KAA
76.   struct trobj Elf[] = {
77.   	{ SHORT_SWORD, 0, WEAPON_SYM, 1, 1 },
78.   	{ BOW, 0, WEAPON_SYM, 1, 1 },
79.   	{ ARROW, 0, WEAPON_SYM, 25, 1 },
80.   	{ UNDEF_TYP, 0, ARMOR_SYM, 1, 1 },
81.   	{ 0, 0, 0, 0, 0 }
82.   };
83.   
84.   struct trobj Valkyrie[] = {
85.   	{ LONG_SWORD, 1, WEAPON_SYM, 1, 1 },
86.   	{ SHIELD, 3, ARMOR_SYM, 1, 1 },
87.   	{ FOOD_RATION, 0, FOOD_SYM, 1, 1 },
88.   	{ 0, 0, 0, 0, 0 }
89.   };
90.   
91.   struct trobj Healer[] = {
92.   	{ STETHOSCOPE, 0, TOOL_SYM, 1, 0 },
93.   	{ POT_HEALING, 0, POTION_SYM, 4, 0 },
94.   	{ POT_EXTRA_HEALING, 0, POTION_SYM, 4, 0 },
95.   	{ APPLE, 0, FOOD_SYM, 5, 0 },
96.   	{ 0, 0, 0, 0, 0}
97.   };
98.   #endif /* KAA /**/
99.   
100.  struct trobj Archeologist[] = {
101.  	{ STUDDED_LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1 },
102.  	{ UNDEF_TYP, 0, POTION_SYM, 2, 0 },
103.  	{ FOOD_RATION, 0, FOOD_SYM, 3, 1 },
104.  	{ PICK_AXE, UNDEF_SPE, TOOL_SYM, 1, 0 },
105.  	{ ICE_BOX, 0, TOOL_SYM, 1, 0 },
106.  	{ 0, 0, 0, 0, 0}
107.  };
108.  
109.  struct trobj Tinopener[] = {
110.  	{ CAN_OPENER, 0, TOOL_SYM, 1, 1 },
111.  	{ 0, 0, 0, 0, 0 }
112.  };
113.  
114.  #ifdef MARKER
115.  struct trobj Magicmarker[] = {
116.  	{ MAGIC_MARKER, 50, TOOL_SYM, 1, 0 },
117.  	{ 0, 0, 0, 0, 0 }
118.  };
119.  #endif
120.  
121.  #ifdef WALKIES
122.  struct trobj Leash[] = {
123.  	{ LEASH, 0, CHAIN_SYM, 1, 0 },
124.  	{ 0, 0, 0, 0, 0 }
125.  };
126.  #endif
127.  
128.  struct trobj Tourist[] = {
129.  	{ UNDEF_TYP, 0, FOOD_SYM, 10, 1 },
130.  	{ POT_EXTRA_HEALING, 0, POTION_SYM, 2, 0 },
131.  	{ EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1 },
132.  	{ DART, 2, WEAPON_SYM, 25, 1 },	/* quan is variable */
133.  	{ 0, 0, 0, 0, 0 }
134.  };
135.  
136.  struct trobj Wizard[] = {
137.  	{ ELVEN_CLOAK, 0, ARMOR_SYM, 1, 1 },
138.  	{ UNDEF_TYP, UNDEF_SPE, WAND_SYM, 2, 0 },
139.  	{ UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 0 },
140.  	{ UNDEF_TYP, UNDEF_SPE, POTION_SYM, 2, 0 },
141.  	{ UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 0 },
142.  #ifdef SPELLS
143.  	{ UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 1, 0 },
144.  #endif
145.  	{ 0, 0, 0, 0, 0 }
146.  };
147.  
148.  #ifdef NEWCLASS
149.  struct	trobj	Samurai[] = {
150.  	{ KATANA, 0, WEAPON_SYM, 1, 1 },
151.  	{ BOW,    1, WEAPON_SYM, 1, 1 },
152.  	{ ARROW,  0, WEAPON_SYM, 25, 1 },	/* quan is variable */
153.  	{ SPLINT_MAIL, 0, ARMOR_SYM, 1, 1},
154.  	{ 0, 0, 0, 0, 0 }
155.  };
156.  
157.  struct	trobj	Ninja[] = {
158.  	{ KATANA, 0, WEAPON_SYM, 1, 1 },
159.  	{ SHURIKEN, 0, WEAPON_SYM, 25, 1 },	/* quan is variable */
160.  	{ LEATHER_ARMOR, 1, ARMOR_SYM, 1, 1},
161.  	{ 0, 0, 0, 0, 0 }
162.  };
163.  
164.  struct	trobj	Priest[] = {
165.  	{ CHAIN_MAIL, 0, ARMOR_SYM, 1, 1 },
166.  	{ SHIELD, 0, ARMOR_SYM, 1, 1 },
167.  	{ MACE, 1, WEAPON_SYM, 1, 1 },
168.  #ifdef SPELLS
169.  	{ UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 2, 0 },
170.  #endif
171.  	{ 0, 0, 0, 0, 0 }
172.  };
173.  #endif /* NEWCLASS /**/
174.  
175.  u_init(){
176.  register int i;
177.  char exper = 'y', pc;
178.  extern char readchar();
179.  	if(flags.female)  {	/* should have been set in HACKOPTIONS */
180.  		roles[4] = "Cave-woman";
181.  #ifdef NEWCLASS
182.  		roles[7] = "Priestess";
183.  #endif
184.  	}
185.  	for(i = 0; i < NR_OF_ROLES; i++)
186.  		rolesyms[i] = roles[i][0];
187.  	rolesyms[i] = 0;
188.  
189.  	if(pc = pl_character[0]) {
190.  		if('a' <= pc && pc <= 'z') pc += 'A'-'a';
191.  		if((i = role_index(pc)) >= 0)
192.  			goto got_suffix;	/* implies experienced */
193.  		printf("\nUnknown role: %c\n", pc);
194.  		pl_character[0] = pc = 0;
195.  	}
196.  
197.  	printf("\nShall I pick a character for you (yes, no, or quit) ? [ynq] ");
198.  
199.  	while(!index("yYnNqQ", (exper = readchar())))	bell();
200.  
201.  	printf("%c\n", exper);		/* echo */
202.  
203.  	if (index("qQ", exper)) exit(0);
204.  
205.  	if(index("Yy", exper)) {
206.  		exper = 0;
207.  		goto beginner;
208.  	}
209.  
210.  	printf("\n Tell me what kind of character you are:\n");
211.  	printf(" Are you");
212.  	for(i = 0; i < NR_OF_ROLES; i++) {
213.  		printf(" %s %s", index("AEIOU",roles[i][0]) ? "an" : "a", roles[i]);
214.  		if((((i + 1) % 4) == 0) && (i != NR_OF_ROLES -1)) printf(",\n\t");
215.  		else if(i < NR_OF_ROLES - 2)	printf(",");
216.  		if(i == NR_OF_ROLES - 2)	printf(" or");
217.  	}
218.  	printf("? [%s or q(quit)] ", rolesyms);
219.  
220.  	while(pc = readchar()) {
221.  		if (pc == 'q' || pc == 'Q') exit(0);
222.  		if('a' <= pc && pc <= 'z') pc += 'A'-'a';
223.  		if((i = role_index(pc)) >= 0) {
224.  			printf("%c\n", pc);	/* echo */
225.  			(void) fflush(stdout);	/* should be seen */
226.  			break;
227.  		}
228.  		if(pc == '\n') break;
229.  		bell();
230.  	}
231.  	if(pc == '\n')	pc = 0;
232.  
233.  beginner:
234.  	if(!pc) {
235.  		i = rn2(NR_OF_ROLES);
236.  		pc = rolesyms[i];
237.  		printf("\nThis game you will be %s %s%s.\n",
238.  			(exper || index("AEIOU", roles[i][0])) ? "an" : "a",
239.  			exper ? "experienced " : "", roles[i]);
240.  		getret();
241.  		/* give him some feedback in case mklev takes much time */
242.  		(void) putchar('\n');
243.  		(void) fflush(stdout);
244.  	}
245.  	if(exper) {
246.  		roles[i][0] = pc;
247.  	}
248.  
249.  got_suffix:
250.  
251.  	(void) strncpy(pl_character, roles[i], PL_CSIZ-1);
252.  	pl_character[PL_CSIZ-1] = 0;
253.  	flags.beginner = 1;
254.  	u = zerou;
255.  	u.usym = '@';
256.  	u.ulevel = 1;
257.  #ifdef SPELLS
258.  	u.uen = u.uenmax = 1;
259.  #endif
260.  #ifdef PRAYERS
261.  	u.ublesscnt = 300;			/* no prayers just yet */
262.  	u.ublessed = 0;				/* not worthy yet */
263.  	u.ugangr   = 0;				/* gods not angry */
264.  #endif
265.  #ifdef KAA
266.  	u.mh = u.mhmax = u.umonnum = u.mtimedone = 0;
267.  #endif
268.  	init_uhunger();
269.  #ifdef QUEST
270.  	u.uhorizon = 6;
271.  #endif
272.  	uarm = uarm2 = uarmh = uarms = uarmg = uwep = uball = uchain =
273.  	uleft = uright = 0;
274.  #ifdef SPELLS
275.  	for (i = 0; i <= MAXSPELL; i++) spl_book[i].sp_id = NO_SPELL;
276.  #endif
277.  	switch(pc) {
278.  	case 'c':
279.  	case 'C':
280.  		Cave_man[2].trquan = 12 + rnd(9)*rnd(9);
281.  		u.uhp = u.uhpmax = 16;
282.  		u.ustr = u.ustrmax = 18;
283.  		ini_inv(Cave_man);
284.  		break;
285.  	case 't':
286.  	case 'T':
287.  #ifdef KAA
288.  		objects[POT_EXTRA_HEALING].oc_name_known=1;
289.  #endif
290.  		Tourist[3].trquan = 20 + rnd(20);
291.  		u.ugold = u.ugold0 = rnd(1000);
292.  		u.uhp = u.uhpmax = 10;
293.  		u.ustr = u.ustrmax = 8;
294.  		ini_inv(Tourist);
295.  		if(!rn2(25)) ini_inv(Tinopener);
296.  #ifdef MARKER
297.  		else if(!rn2(25)) ini_inv(Magicmarker);
298.  #endif
299.  #ifdef WALKIES
300.  		else if(!rn2(25)) ini_inv(Leash);
301.  #endif
302.  		break;
303.  	case 'w':
304.  	case 'W':
305.  		for(i=1; i<=4; i++) if(!rn2(5))
306.  			Wizard[i].trquan += rn2(3) - 1;
307.  		u.uhp = u.uhpmax = 15;
308.  		u.ustr = u.ustrmax = 16;
309.  #ifdef SPELLS
310.  		u.uen = u.uenmax += rn2(4);
311.  #endif
312.  		ini_inv(Wizard);
313.  #ifdef MARKER
314.  		if(!rn2(5)) ini_inv(Magicmarker);
315.  #endif
316.  		break;
317.  	case 'a':
318.  	case 'A':
319.  		Fast = INTRINSIC;
320.  		Stealth = INTRINSIC;
321.  		u.uhp = u.uhpmax = 12;
322.  		u.ustr = u.ustrmax = 10;
323.  		ini_inv(Archeologist);
324.  		if(!rn2(10)) ini_inv(Tinopener);
325.  #ifdef MARKER
326.  		else if(!rn2(10)) ini_inv(Magicmarker);
327.  #endif
328.  		break;
329.  #ifdef KAA
330.  	case 'e':
331.  	case 'E':
332.  		Elf[2].trquan = 15+rnd(20);
333.  		Elf[3].trotyp = (rn2(2) ? ELFIN_CHAIN_MAIL : ELVEN_CLOAK);
334.  		Fast = INTRINSIC;
335.  		HSee_invisible = INTRINSIC;
336.  		u.uhp = u.uhpmax = 16;
337.  		u.ustr = u.ustrmax = 16;
338.  		ini_inv(Elf);
339.  		break;
340.  	case 'v':
341.  	case 'V':
342.  		Stealth = INTRINSIC;
343.  		HCold_resistance = INTRINSIC;
344.  		flags.female = TRUE;
345.  		u.uhp = u.uhpmax = 16;
346.  		u.ustr = u.ustrmax = 17;
347.  		ini_inv(Valkyrie);
348.  		break;
349.  	case 'h':
350.  	case 'H':
351.  		objects[POT_HEALING].oc_name_known=1;
352.  		objects[POT_EXTRA_HEALING].oc_name_known=1;
353.  		HPoison_resistance = INTRINSIC;
354.  		u.uhp = u.uhpmax = 16;
355.  		u.ustr = u.ustrmax = 15;
356.  		ini_inv(Healer);
357.  		break;
358.  #endif
359.  	case 'k':
360.  	case 'K':
361.  		u.uhp = u.uhpmax = 12;
362.  		u.ustr = u.ustrmax = 10;
363.  		ini_inv(Knight);
364.  		break;
365.  	case 'f':
366.  	case 'F':
367.  		u.uhp = u.uhpmax = 14;
368.  		u.ustr = u.ustrmax = 17;
369.  		ini_inv(Fighter);
370.  		break;
371.  #ifdef NEWCLASS
372.  	case 's':
373.  	case 'S':
374.  		Fast = INTRINSIC;
375.  		u.uhp = u.uhpmax = 16;
376.  		u.ustr = u.ustrmax = 16;
377.  		Samurai[2].trquan = 12 + rnd(9)*rnd(9);
378.  		ini_inv(Samurai);
379.  		break;
380.  	case 'n':
381.  	case 'N':
382.  		Fast = INTRINSIC;
383.  		Stealth = INTRINSIC;
384.  		u.uhp = u.uhpmax = 15;
385.  		u.ustr = u.ustrmax = 10;
386.  		Ninja[1].trquan = 12 + rnd(9)*rnd(9);
387.  		ini_inv(Ninja);
388.  		break;
389.  	case 'p':
390.  	case 'P':
391.  		u.uhp = u.uhpmax = 13;
392.  		u.ustr = u.ustrmax = 15;
393.  # ifdef SPELLS
394.  		u.uen = u.uenmax += rn2(4);
395.  # endif
396.  		ini_inv(Priest);
397.  # ifdef MARKER
398.  		if(!rn2(10)) ini_inv(Magicmarker);
399.  # endif
400.  		break;
401.  #endif /* NEWCLASS /**/
402.  	default:	/* impossible */
403.  		u.uhp = u.uhpmax = 12;
404.  		u.ustr = u.ustrmax = 16;
405.  	}
406.  	find_ac();
407.  	if(!rn2(20)) {
408.  		register int d = rn2(7) - 2;	/* biased variation */
409.  		u.ustr += d;
410.  		u.ustrmax += d;
411.  	}
412.  
413.  #ifdef WIZARD
414.  	if(wizard) wiz_inv();
415.  #endif
416.  
417.  	/* make sure he can carry all he has - especially for T's */
418.  	while(inv_weight() > 0 && u.ustr < 118)
419.  		u.ustr++, u.ustrmax++;
420.  }
421.  
422.  ini_inv(trop) register struct trobj *trop; {
423.  register struct obj *obj;
424.  extern struct obj *mkobj();
425.  	while(trop->trolet) {
426.  		obj = mkobj(trop->trolet);
427.  		obj->known = trop->trknown;
428.  		/* not obj->dknown = 1; - let him look at it at least once */
429.  		obj->cursed = 0;
430.  		if(obj->olet == WEAPON_SYM){
431.  			obj->quan = trop->trquan;
432.  			trop->trquan = 1;
433.  		}
434.  		if(trop->trspe != UNDEF_SPE)
435.  			obj->spe = trop->trspe;
436.  		if(trop->trotyp != UNDEF_TYP)
437.  			obj->otyp = trop->trotyp;
438.  		else
439.  			if(obj->otyp == WAN_WISHING)	/* gitpyr!robert */
440.  				obj->otyp = WAN_DEATH;
441.  		obj->owt = weight(obj);	/* defined after setting otyp+quan */
442.  		obj = addinv(obj);
443.  		if(obj->olet == ARMOR_SYM){
444.  			switch(obj->otyp){
445.  			case SHIELD:
446.  				if(!uarms) setworn(obj, W_ARMS);
447.  				break;
448.  			case HELMET:
449.  				if(!uarmh) setworn(obj, W_ARMH);
450.  				break;
451.  			case PAIR_OF_GLOVES:
452.  				if(!uarmg) setworn(obj, W_ARMG);
453.  				break;
454.  			case ELVEN_CLOAK:
455.  				if(!uarm2)
456.  					setworn(obj, W_ARM);
457.  				break;
458.  			default:
459.  				if(!uarm) setworn(obj, W_ARM);
460.  			}
461.  		}
462.  		/* below changed by GAN 01/09/87 to allow wielding of
463.  		 * pick-axe or can-opener if there is no weapon
464.  		 */
465.  		if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE ||
466.  		   obj->otyp == CAN_OPENER)
467.  			if(!uwep) setuwep(obj);
468.  #ifndef PYRAMID_BUG
469.  		if(--trop->trquan) continue;	/* make a similar object */
470.  #else
471.  		if(trop->trquan) {		/* check if zero first */
472.  			--trop->trquan;
473.  			if(trop->trquan)
474.  				continue;	/* make a similar object */
475.  		}
476.  #endif
477.  		trop++;
478.  	}
479.  }
480.  
481.  #ifdef WIZARD
482.  wiz_inv(){
483.  register struct trobj *trop = &Extra_objs[0];
484.  extern char *getenv();
485.  register char *ep = getenv("INVENT");
486.  register int type;
487.  	while(ep && *ep) {
488.  		type = atoi(ep);
489.  		ep = index(ep, ',');
490.  		if(ep) while(*ep == ',' || *ep == ' ') ep++;
491.  		if(type <= 0 || type > NROFOBJECTS) continue;
492.  		trop->trotyp = type;
493.  		trop->trolet = objects[type].oc_olet;
494.  		trop->trspe = 4;
495.  		trop->trknown = 1;
496.  		trop->trquan = 1;
497.  		ini_inv(trop);
498.  	}
499.  	/* give him a wand of wishing by default */
500.  	trop->trotyp = WAN_WISHING;
501.  	trop->trolet = WAND_SYM;
502.  	trop->trspe = 20;
503.  	trop->trknown = 1;
504.  	trop->trquan = 1;
505.  	ini_inv(trop);
506.  }
507.  #endif /* WIZARD /**/
508.  
509.  plnamesuffix() {
510.  register char *p;
511.  	if(p = rindex(plname, '-')) {
512.  		*p = 0;
513.  		pl_character[0] = p[1];
514.  		pl_character[1] = 0;
515.  		if(!plname[0]) {
516.  			askname();
517.  			plnamesuffix();
518.  		}
519.  	}
520.  }
521.  
522.  role_index(pc)
523.  char pc;
524.  {		/* must be called only from u_init() */
525.  		/* so that rolesyms[] is defined */
526.  	register char *cp;
527.  
528.  	if(cp = index(rolesyms, pc))
529.  		return(cp - rolesyms);
530.  	return(-1);
531.  }