1 | /* SCCS Id: @(#)botl.c 3.3 96/07/15 */
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_DCL void NDECL(bot1);
20 | STATIC_DCL 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 | STATIC_DCL const char *NDECL(rank);
44 |
45 | #ifdef OVL1
46 |
47 | /* convert experience level (1..30) to rank index (0..8) */
48 | int xlev_to_rank(xlev)
49 | int xlev;
50 | {
51 | return (xlev <= 2) ? 0 : (xlev <= 30) ? ((xlev + 2) / 4) : 8;
52 | }
53 |
54 | #if 0 /* not currently needed */
55 | /* convert rank index (0..8) to experience level (1..30) */
56 | int rank_to_xlev(rank)
57 | int rank;
58 | {
59 | return (rank <= 0) ? 1 : (rank <= 8) ? ((rank * 4) - 2) : 30;
60 | }
61 | #endif
62 |
63 | const char *
64 | rank_of(lev, monnum, female)
65 | int lev;
66 | short monnum;
67 | boolean female;
68 | {
69 | register struct Role *role;
70 | register int i;
71 |
72 |
73 | /* Find the role */
74 | for (role = (struct Role *) roles; role->name.m; role++)
75 | if (monnum == role->malenum || monnum == role->femalenum)
76 | break;
77 | if (!role->name.m)
78 | role = &urole;
79 |
80 | /* Find the rank */
81 | for (i = xlev_to_rank((int)lev); i >= 0; i--) {
82 | if (female && role->rank[i].f) return (role->rank[i].f);
83 | if (role->rank[i].m) return (role->rank[i].m);
84 | }
85 |
86 | /* Try the role name, instead */
87 | if (female && role->name.f) return (role->name.f);
88 | else if (role->name.m) return (role->name.m);
89 | return ("Player");
90 | }
91 |
92 |
93 | STATIC_OVL const char *
94 | rank()
95 | {
96 | return(rank_of(u.ulevel, Role_switch, flags.female));
97 | }
98 |
99 | int
100 | title_to_mon(str, rank_indx, title_length)
101 | const char *str;
102 | int *rank_indx, *title_length;
103 | {
104 | register int i, j;
105 |
106 |
107 | /* Loop through each of the roles */
108 | for (i = 0; roles[i].name.m; i++)
109 | for (j = 0; j < 9; j++) {
110 | if (roles[i].rank[j].m && !strncmpi(str,
111 | roles[i].rank[j].m, strlen(roles[i].rank[j].m))) {
112 | if (rank_indx) *rank_indx = j;
113 | if (title_length) *title_length = strlen(roles[i].rank[j].m);
114 | return roles[i].malenum;
115 | }
116 | if (roles[i].rank[j].f && !strncmpi(str,
117 | roles[i].rank[j].f, strlen(roles[i].rank[j].f))) {
118 | if (rank_indx) *rank_indx = j;
119 | if (title_length) *title_length = strlen(roles[i].rank[j].f);
120 | return ((roles[i].femalenum != NON_PM) ?
121 | roles[i].femalenum : roles[i].malenum);
122 | }
123 | }
124 | return NON_PM;
125 | }
126 |
127 | #endif /* OVL1 */
128 | #ifdef OVLB
129 |
130 | void
131 | max_rank_sz()
132 | {
133 | register int i, r, maxr = 0;
134 | for (i = 0; i < 9; i++) {
135 | if (urole.rank[i].m && (r = strlen(urole.rank[i].m)) > maxr) maxr = r;
136 | if (urole.rank[i].f && (r = strlen(urole.rank[i].f)) > maxr) maxr = r;
137 | }
138 | mrank_sz = maxr;
139 | return;
140 | }
141 |
142 | #endif /* OVLB */
143 | #ifdef OVL0
144 |
145 | #ifdef SCORE_ON_BOTL
146 | long
147 | botl_score()
148 | {
149 | int deepest = deepest_lev_reached(FALSE);
150 | long ugold = u.ugold + hidden_gold();
151 |
152 | if ((ugold -= u.ugold0) < 0L) ugold = 0L;
153 | return ugold + u.urexp + (long)(50 * (deepest - 1))
154 | + (long)(deepest > 30 ? 10000 :
155 | deepest > 20 ? 1000*(deepest - 20) : 0);
156 | }
157 | #endif
158 |
159 | STATIC_OVL void
160 | bot1()
161 | {
162 | char newbot1[MAXCO];
163 | register char *nb;
164 | register int i,j;
165 |
166 | Strcpy(newbot1, plname);
167 | if('a' <= newbot1[0] && newbot1[0] <= 'z') newbot1[0] += 'A'-'a';
168 | newbot1[10] = 0;
169 | Sprintf(nb = eos(newbot1)," the ");
170 |
171 | if (Upolyd) {
172 | char mbot[BUFSZ];
173 | int k = 0;
174 |
175 | Strcpy(mbot, mons[u.umonnum].mname);
176 | while(mbot[k] != 0) {
177 | if ((k == 0 || (k > 0 && mbot[k-1] == ' ')) &&
178 | 'a' <= mbot[k] && mbot[k] <= 'z')
179 | mbot[k] += 'A' - 'a';
180 | k++;
181 | }
182 | Sprintf(nb = eos(nb), mbot);
183 | } else
184 | Sprintf(nb = eos(nb), rank());
185 |
186 | Sprintf(nb = eos(nb)," ");
187 | i = mrank_sz + 15;
188 | j = (nb + 2) - newbot1; /* aka strlen(newbot1) but less computation */
189 | if((i - j) > 0)
190 | Sprintf(nb = eos(nb),"%*s", i-j, " "); /* pad with spaces */
191 | if (ACURR(A_STR) > 18) {
192 | if (ACURR(A_STR) > STR18(100))
193 | Sprintf(nb = eos(nb),"St:%2d ",ACURR(A_STR)-100);
194 | else if (ACURR(A_STR) < STR18(100))
195 | Sprintf(nb = eos(nb), "St:18/%02d ",ACURR(A_STR)-18);
196 | else
197 | Sprintf(nb = eos(nb),"St:18/** ");
198 | } else
199 | Sprintf(nb = eos(nb), "St:%-1d ",ACURR(A_STR));
200 | Sprintf(nb = eos(nb),
201 | "Dx:%-1d Co:%-1d In:%-1d Wi:%-1d Ch:%-1d",
202 | ACURR(A_DEX), ACURR(A_CON), ACURR(A_INT), ACURR(A_WIS), ACURR(A_CHA));
203 | Sprintf(nb = eos(nb), (u.ualign.type == A_CHAOTIC) ? " Chaotic" :
204 | (u.ualign.type == A_NEUTRAL) ? " Neutral" : " Lawful");
205 | #ifdef SCORE_ON_BOTL
206 | if (flags.showscore)
207 | Sprintf(nb = eos(nb), " S:%ld", botl_score());
208 | #endif
209 | curs(WIN_STATUS, 1, 0);
210 | putstr(WIN_STATUS, 0, newbot1);
211 | }
212 |
213 | /* provide the name of the current level for display by various ports */
214 | int
215 | describe_level(buf)
216 | char *buf;
217 | {
218 | int ret = 1;
219 |
220 | /* TODO: Add in dungeon name */
221 | if (Is_knox(&u.uz))
222 | Sprintf(buf, "%s ", dungeons[u.uz.dnum].dname);
223 | else if (In_quest(&u.uz))
224 | Sprintf(buf, "Home %d ", dunlev(&u.uz));
225 | else if (In_endgame(&u.uz))
226 | Sprintf(buf,
227 | Is_astralevel(&u.uz) ? "Astral Plane " : "End Game ");
228 | else {
229 | /* ports with more room may expand this one */
230 | Sprintf(buf, "Dlvl:%-2d ", depth(&u.uz));
231 | ret = 0;
232 | }
233 | return ret;
234 | }
235 |
236 | STATIC_OVL void
237 | bot2()
238 | {
239 | char newbot2[MAXCO];
240 | register char *nb;
241 | int hp, hpmax;
242 | int cap = near_capacity();
243 |
244 | hp = Upolyd ? u.mh : u.uhp;
245 | hpmax = Upolyd ? u.mhmax : u.uhpmax;
246 |
247 | if(hp < 0) hp = 0;
248 | (void) describe_level(newbot2);
249 | Sprintf(nb = eos(newbot2),
250 | "%c:%-2ld HP:%d(%d) Pw:%d(%d) AC:%-2d", oc_syms[GOLD_CLASS],
251 | u.ugold, hp, hpmax, u.uen, u.uenmax, u.uac);
252 |
253 | if (Upolyd)
254 | Sprintf(nb = eos(nb), " HD:%d", mons[u.umonnum].mlevel);
255 | #ifdef EXP_ON_BOTL
256 | else if(flags.showexp)
257 | Sprintf(nb = eos(nb), " Xp:%u/%-1ld", u.ulevel,u.uexp);
258 | #endif
259 | else
260 | Sprintf(nb = eos(nb), " Exp:%u", u.ulevel);
261 |
262 | if(flags.time)
263 | Sprintf(nb = eos(nb), " T:%ld", moves);
264 | if(strcmp(hu_stat[u.uhs], " ")) {
265 | Sprintf(nb = eos(nb), " ");
266 | Strcat(newbot2, hu_stat[u.uhs]);
267 | }
268 | if(Confusion) Sprintf(nb = eos(nb), " Conf");
269 | if(Sick) {
270 | if (u.usick_type & SICK_VOMITABLE)
271 | Sprintf(nb = eos(nb), " FoodPois");
272 | if (u.usick_type & SICK_NONVOMITABLE)
273 | Sprintf(nb = eos(nb), " Ill");
274 | }
275 | if(Blind) Sprintf(nb = eos(nb), " Blind");
276 | if(Stunned) Sprintf(nb = eos(nb), " Stun");
277 | if(Hallucination) Sprintf(nb = eos(nb), " Hallu");
278 | if(Slimed) Sprintf(nb = eos(nb), " Slime");
279 | if(cap > UNENCUMBERED)
280 | Sprintf(nb = eos(nb), " %s", enc_stat[cap]);
281 | curs(WIN_STATUS, 1, 1);
282 | putstr(WIN_STATUS, 0, newbot2);
283 | }
284 |
285 | void
286 | bot()
287 | {
288 | bot1();
289 | bot2();
290 | flags.botl = flags.botlx = 0;
291 | }
292 |
293 | #endif /* OVL0 */
294 |
295 | /*botl.c*/