Source:NetHack 3.2.0/botl.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to botl.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/botl.c#line123]], for example.

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

1.    /*	SCCS Id: @(#)botl.c	3.2	95/05/31	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    
7.    #ifdef OVL0
8.    extern const char *hu_stat[];	/* defined in eat.c */
9.    
10.   const char *enc_stat[] = {
11.   	"",
12.   	"Burdened",
13.   	"Stressed",
14.   	"Strained",
15.   	"Overtaxed",
16.   	"Overloaded"
17.   };
18.   
19.   static void NDECL(bot1);
20.   static void NDECL(bot2);
21.   #endif /* OVL0 */
22.   
23.   /* MAXCO must hold longest uncompressed status line, and must be larger
24.    * than COLNO
25.    *
26.    * longest practical second status line at the moment is
27.    *	Astral Plane $:12345 HP:700(700) Pw:111(111) AC:-127 Xp:30/123456789
28.    *	T:123456 Satiated Conf FoodPois Ill Blind Stun Hallu Overloaded
29.    * -- or somewhat over 130 characters
30.    */
31.   #if COLNO <= 140
32.   #define MAXCO 160
33.   #else
34.   #define MAXCO (COLNO+20)
35.   #endif
36.   
37.   #ifndef OVLB
38.   STATIC_DCL int mrank_sz;
39.   #else /* OVLB */
40.   STATIC_OVL NEARDATA int mrank_sz = 0; /* loaded by max_rank_sz (from u_init) */
41.   #endif /* OVLB */
42.   
43.   struct rank_title {
44.   #ifdef _DCC
45.       const char *m;		/* male title */
46.       const char *f;		/* female title, or 0 if same as male */
47.   #else
48.       char const * const	m;	/* male title */
49.       char const * const	f;	/* female title, or 0 if same as male */
50.   #endif
51.   };
52.   struct class_ranks {
53.       char		plclass, fill_;
54.       short		mplayer_class;
55.       struct rank_title	titles[9];
56.   };
57.   
58.   STATIC_DCL const struct rank_title *FDECL(rank_array, (CHAR_P));
59.   STATIC_DCL const char *NDECL(rank);
60.   
61.   #ifdef OVL1
62.   
63.   /* 9 pairs of ranks for each class */
64.   
65.   static const
66.   struct class_ranks all_classes[] = {
67.     {					'A',0,	PM_ARCHEOLOGIST, {
68.   	{"Digger",	0},
69.   	{"Field Worker",0},
70.   	{"Investigator",0},
71.   	{"Exhumer",	0},
72.   	{"Excavator",	0},
73.   	{"Spelunker",	0},
74.   	{"Speleologist",0},
75.   	{"Collector",	0},
76.   	{"Curator",	0}
77.     } },
78.     {					'B',0,	PM_BARBARIAN, {
79.   	{"Plunderer",	"Plunderess"},
80.   	{"Pillager",	0},
81.   	{"Bandit",	0},
82.   	{"Brigand",	0},
83.   	{"Raider",	0},
84.   	{"Reaver",	0},
85.   	{"Slayer",	0},
86.   	{"Chieftain",	"Chieftainess"},
87.   	{"Conqueror",	"Conqueress"}
88.     } },
89.     {					'C',0,	PM_CAVEMAN, {
90.   	{"Troglodyte",	0},
91.   	{"Aborigine",	0},
92.   	{"Wanderer",	0},
93.   	{"Vagrant",	0},
94.   	{"Wayfarer",	0},
95.   	{"Roamer",	0},
96.   	{"Nomad",	0},
97.   	{"Rover",	0},
98.   	{"Pioneer",	0}
99.     } },
100.    {					'E',0,	PM_ELF, {
101.  	{"Edhel",	"Elleth"},
102.  	{"Edhel",	"Elleth"},	/* elf-maid */
103.  	{"Ohtar",	"Ohtie"},	/* warrior */
104.  	{"Kano",			/* commander (Q.) ['a] */
105.  			"Kanie"}, /* educated guess, until further research- SAC */
106.  	{"Arandur",		  /* king's servant, minister (Q.) - guess */
107.  			"Aranduriel"},	/* educated guess */
108.  	{"Hir",		"Hiril"},	/* lord, lady (S.) ['ir] */
109.  	{"Aredhel",	"Arwen"},	/* noble elf, maiden (S.) */
110.  	{"Ernil",	"Elentariel"},	/* prince (S.), elf-maiden (Q.) */
111.  	{"Elentar",	"Elentari"}	/* Star-king, -queen (Q.) */
112.    } },
113.    {					'H',0,	PM_HEALER, {
114.  	{"Rhizotomist",  0},
115.  	{"Empiric",	0},
116.  	{"Embalmer",	0},
117.  	{"Dresser",	0},
118.  	{"Medici ossium",	0},
119.  	{"Herbalist",	0},
120.  	{"Magister",	0},
121.  	{"Physician",	0},
122.  	{"Chirurgeon",	0}
123.    } },
124.    {					'K',0,	PM_KNIGHT, {
125.  	{"Gallant",	0},
126.  	{"Esquire",	0},
127.  	{"Bachelor",	0},
128.  	{"Sergeant",	0},
129.  	{"Knight",	0},
130.  	{"Banneret",	0},
131.  	{"Chevalier",	0},
132.  	{"Seignieur",	0},
133.  	{"Paladin",	0}
134.    } },
135.    {					'P',0,	PM_PRIEST, {
136.  	{"Aspirant",	0},
137.  	{"Acolyte",	0},
138.  	{"Adept",	0},
139.  	{"Priest",	"Priestess"},
140.  	{"Curate",	0},
141.  	{"Canon",	"Canoness"},
142.  	{"Lama",	0},
143.  	{"Patriarch",	"Matriarch"},
144.  	{"High Priest", "High Priestess"}
145.    } },
146.    {					'R',0,	PM_ROGUE, {
147.  	{"Footpad",	0},
148.  	{"Cutpurse",	0},
149.  	{"Rogue",	0},
150.  	{"Pilferer",	0},
151.  	{"Robber",	0},
152.  	{"Burglar",	0},
153.  	{"Filcher",	0},
154.  	{"Magsman",	"Magswoman"},
155.  	{"Thief",	0}
156.    } },
157.    {					'S',0,	PM_SAMURAI, {
158.  	{"Hatamoto",	0},  /* Banner Knight */
159.  	{"Ronin",	0},  /* no allegiance */
160.  	{"Ninja",	0},  /* secret society */
161.  	{"Joshu",	0},  /* heads a castle */
162.  	{"Ryoshu",	0},  /* has a territory */
163.  	{"Kokushu",	0},  /* heads a province */
164.  	{"Daimyo",	0},  /* a samurai lord */
165.  	{"Kuge",	0},  /* Noble of the Court */
166.  	{"Shogun",	0}   /* supreme commander, warlord */
167.    } },
168.  #ifdef TOURIST
169.    {					'T',0,	PM_TOURIST, {
170.  	{"Rambler",	0},
171.  	{"Sightseer",	0},
172.  	{"Excursionist",0},
173.  	{"Peregrinator","Peregrinatrix"},
174.  	{"Traveler",	0},
175.  	{"Journeyer",	0},
176.  	{"Voyager",	0},
177.  	{"Explorer",	0},
178.  	{"Adventurer",	0}
179.    } },
180.  #endif
181.    {					'V',0,	PM_VALKYRIE, {
182.  	{"Stripling",	0},
183.  	{"Skirmisher",	0},
184.  	{"Fighter",	0},
185.  	{"Man-at-arms", "Woman-at-arms"},
186.  	{"Warrior",	0},
187.  	{"Swashbuckler",0},
188.  	{"Hero",	"Heroine"},
189.  	{"Champion",	0},
190.  	{"Lord",	"Lady"}
191.    } },
192.    {					'W',0,	PM_WIZARD, {
193.  	{"Evoker",	0},
194.  	{"Conjurer",	0},
195.  	{"Thaumaturge", 0},
196.  	{"Magician",	0},
197.  	{"Enchanter",	"Enchantress"},
198.  	{"Sorcerer",	"Sorceress"},
199.  	{"Necromancer", 0},
200.  	{"Wizard",	0},
201.  	{"Mage",	0}
202.    } },
203.  };
204.  
205.  STATIC_OVL const struct rank_title *
206.  rank_array(pc)
207.  char pc;
208.  {
209.  	register int i;
210.  
211.  	for (i = 0; i < SIZE(all_classes); i++)
212.  	    if (all_classes[i].plclass == pc) return all_classes[i].titles;
213.  	return 0;
214.  }
215.  
216.  /* convert experience level (1..30) to rank index (0..8) */
217.  int xlev_to_rank(xlev)
218.  int xlev;
219.  {
220.  	return (xlev <= 2) ? 0 : (xlev <= 30) ? ((xlev + 2) / 4) : 8;
221.  }
222.  
223.  #if 0	/* not currently needed */
224.  /* convert rank index (0..8) to experience level (1..30) */
225.  int rank_to_xlev(rank)
226.  int rank;
227.  {
228.  	return (rank <= 0) ? 1 : (rank <= 8) ? ((rank * 4) - 2) : 30;
229.  }
230.  #endif
231.  
232.  const char *
233.  rank_of(lev, pc, female)
234.  int lev;
235.  char pc;
236.  boolean female;
237.  {
238.  	register int idx = xlev_to_rank((int)lev);
239.  	const struct rank_title *ranks = rank_array(pc);
240.  
241.  	if (ranks)
242.  	    return( female && ranks[idx].f ? ranks[idx].f : ranks[idx].m );
243.  	return(pl_character);
244.  }
245.  
246.  STATIC_OVL const char *
247.  rank()
248.  {
249.  	return(rank_of(u.ulevel, u.role, flags.female));
250.  }
251.  
252.  int
253.  title_to_mon(str, rank_indx, title_length)
254.  const char *str;
255.  int *rank_indx, *title_length;
256.  {
257.  	register int i, j;
258.  	register const struct rank_title *ttl;
259.  
260.  	for (i = 0; i < SIZE(all_classes); i++)
261.  	    for (j = 0; j < 9; j++) {
262.  		ttl = &all_classes[i].titles[j];
263.  		if (!strncmpi(ttl->m, str, strlen(ttl->m))) {
264.  		    if (rank_indx) *rank_indx = j;
265.  		    if (title_length) *title_length = strlen(ttl->m);
266.  		    return all_classes[i].mplayer_class;
267.  		} else if (ttl->f && !strncmpi(ttl->f, str, strlen(ttl->f))) {
268.  		    if (rank_indx) *rank_indx = j;
269.  		    if (title_length) *title_length = strlen(ttl->f);
270.  		    return all_classes[i].plclass == 'C' ? PM_CAVEWOMAN :
271.  			   all_classes[i].plclass == 'P' ? PM_PRIESTESS :
272.  			   all_classes[i].mplayer_class;
273.  		}
274.  	    }
275.  	return NON_PM;
276.  }
277.  
278.  #endif /* OVL1 */
279.  #ifdef OVLB
280.  
281.  void
282.  max_rank_sz()
283.  {
284.  	register int i, r, maxr = 0;
285.  	const struct rank_title *ranks = rank_array(u.role);
286.  
287.  	if (ranks) {
288.  	    for (i = 0; i < 9; i++) {
289.  		if ((r = strlen(ranks[i].m)) > maxr) maxr = r;
290.  		if (ranks[i].f)
291.  		    if ((r = strlen(ranks[i].f)) > maxr) maxr = r;
292.  	    }
293.  	    mrank_sz = maxr;
294.  	} else
295.  	    mrank_sz = strlen(pl_character);
296.  }
297.  
298.  #endif /* OVLB */
299.  #ifdef OVL0
300.  
301.  #ifdef SCORE_ON_BOTL
302.  long
303.  botl_score()
304.  {
305.      int deepest = deepest_lev_reached(FALSE);
306.      long ugold = u.ugold + hidden_gold();
307.  
308.      if ((ugold -= u.ugold0) < 0L) ugold = 0L;
309.      return ugold + u.urexp + (long)(50 * (deepest - 1))
310.  			  + (long)(deepest > 30 ? 10000 :
311.  				   deepest > 20 ? 1000*(deepest - 20) : 0);
312.  }
313.  #endif
314.  
315.  static void
316.  bot1()
317.  {
318.  	char newbot1[MAXCO];
319.  	register char *nb;
320.  	register int i,j;
321.  
322.  	Strcpy(newbot1, plname);
323.  	if('a' <= newbot1[0] && newbot1[0] <= 'z') newbot1[0] += 'A'-'a';
324.  	newbot1[10] = 0;
325.  	Sprintf(nb = eos(newbot1)," the ");
326.  
327.  	if (u.mtimedone) {
328.  		char mbot[BUFSZ];
329.  		int k = 0;
330.  
331.  		Strcpy(mbot, mons[u.umonnum].mname);
332.  		while(mbot[k] != 0) {
333.  		    if ((k == 0 || (k > 0 && mbot[k-1] == ' ')) &&
334.  					'a' <= mbot[k] && mbot[k] <= 'z')
335.  			mbot[k] += 'A' - 'a';
336.  		    k++;
337.  		}
338.  		Sprintf(nb = eos(nb), mbot);
339.  	} else
340.  		Sprintf(nb = eos(nb), rank());
341.  
342.  	Sprintf(nb = eos(nb),"  ");
343.  	i = mrank_sz + 15;
344.  	j = (nb + 2) - newbot1; /* aka strlen(newbot1) but less computation */
345.  	if((i - j) > 0)
346.  		Sprintf(nb = eos(nb),"%*s", i-j, " ");	/* pad with spaces */
347.  	if (ACURR(A_STR) > 18) {
348.  		if (ACURR(A_STR) > 118)
349.  		    Sprintf(nb = eos(nb),"St:%2d ",ACURR(A_STR)-100);
350.  		else if (ACURR(A_STR) < 118)
351.  		    Sprintf(nb = eos(nb), "St:18/%02d ",ACURR(A_STR)-18);
352.  		else
353.  		    Sprintf(nb = eos(nb),"St:18/** ");
354.  	} else
355.  		Sprintf(nb = eos(nb), "St:%-1d ",ACURR(A_STR));
356.  	Sprintf(nb = eos(nb),
357.  		"Dx:%-1d Co:%-1d In:%-1d Wi:%-1d Ch:%-1d",
358.  		ACURR(A_DEX), ACURR(A_CON), ACURR(A_INT), ACURR(A_WIS), ACURR(A_CHA));
359.  	Sprintf(nb = eos(nb), (u.ualign.type == A_CHAOTIC) ? "  Chaotic" :
360.  			(u.ualign.type == A_NEUTRAL) ? "  Neutral" : "  Lawful");
361.  #ifdef SCORE_ON_BOTL
362.  	if (flags.showscore)
363.  	    Sprintf(nb = eos(nb), " S:%ld", botl_score());
364.  #endif
365.  	curs(WIN_STATUS, 1, 0);
366.  	putstr(WIN_STATUS, 0, newbot1);
367.  }
368.  
369.  static void
370.  bot2()
371.  {
372.  	char  newbot2[MAXCO];
373.  	register char *nb;
374.  	int hp, hpmax;
375.  	int cap = near_capacity();
376.  
377.  	hp = u.mtimedone ? u.mh : u.uhp;
378.  	hpmax = u.mtimedone ? u.mhmax : u.uhpmax;
379.  
380.  	if(hp < 0) hp = 0;
381.  /* TODO:	Add in dungeon name */
382.  	if (Is_knox(&u.uz))
383.  		Sprintf(newbot2, "%s ", dungeons[u.uz.dnum].dname);
384.  	else if (In_quest(&u.uz))
385.  		Sprintf(newbot2, "Home %d ", dunlev(&u.uz));
386.  	else if (In_endgame(&u.uz))
387.  		Sprintf(newbot2,
388.  			Is_astralevel(&u.uz) ? "Astral Plane " : "End Game ");
389.  	else
390.  		Sprintf(newbot2, "Dlvl:%-2d ", depth(&u.uz));
391.  	Sprintf(nb = eos(newbot2),
392.  		"%c:%-2ld HP:%d(%d) Pw:%d(%d) AC:%-2d", oc_syms[GOLD_CLASS],
393.  		u.ugold, hp, hpmax, u.uen, u.uenmax, u.uac);
394.  
395.  	if (u.mtimedone)
396.  		Sprintf(nb = eos(nb), " HD:%d", mons[u.umonnum].mlevel);
397.  #ifdef EXP_ON_BOTL
398.  	else if(flags.showexp)
399.  		Sprintf(nb = eos(nb), " Xp:%u/%-1ld", u.ulevel,u.uexp);
400.  #endif
401.  	else
402.  		Sprintf(nb = eos(nb), " Exp:%u", u.ulevel);
403.  
404.  	if(flags.time)
405.  	    Sprintf(nb = eos(nb), " T:%ld", moves);
406.  	if(strcmp(hu_stat[u.uhs], "        ")) {
407.  		Sprintf(nb = eos(nb), " ");
408.  		Strcat(newbot2, hu_stat[u.uhs]);
409.  	}
410.  	if(Confusion)	   Sprintf(nb = eos(nb), " Conf");
411.  	if(Sick) {
412.  		if (u.usick_type & SICK_VOMITABLE)
413.  			   Sprintf(nb = eos(nb), " FoodPois");
414.  		if (u.usick_type & SICK_NONVOMITABLE)
415.  			   Sprintf(nb = eos(nb), " Ill");
416.  	}
417.  	if(Blind)	   Sprintf(nb = eos(nb), " Blind");
418.  	if(Stunned)	   Sprintf(nb = eos(nb), " Stun");
419.  	if(Hallucination)  Sprintf(nb = eos(nb), " Hallu");
420.  	if(cap > UNENCUMBERED)
421.  		Sprintf(nb = eos(nb), " %s", enc_stat[cap]);
422.  	curs(WIN_STATUS, 1, 1);
423.  	putstr(WIN_STATUS, 0, newbot2);
424.  }
425.  
426.  void
427.  bot()
428.  {
429.  	bot1();
430.  	bot2();
431.  	flags.botl = flags.botlx = 0;
432.  }
433.  
434.  #endif /* OVL0 */
435.  
436.  /*botl.c*/