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*/