1 | /* SCCS Id: @(#)mondata.c 3.3 2000/07/14 */ 2 | /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3 | /* NetHack may be freely redistributed. See license for details. */ 4 | 5 | #include "hack.h" 6 | #include "eshk.h" 7 | #include "epri.h" 8 | 9 | /* These routines provide basic data for any type of monster. */ 10 | 11 | #ifdef OVLB 12 | 13 | void 14 | set_mon_data(mon, ptr, flag) 15 | struct monst *mon; 16 | struct permonst *ptr; 17 | int flag; 18 | { 19 | mon->data = ptr; 20 | if (flag == -1) return; /* "don't care" */ 21 | 22 | if (flag == 1) 23 | mon->mintrinsics |= (ptr->mresists & 0x00FF); 24 | else 25 | mon->mintrinsics = (ptr->mresists & 0x00FF); 26 | return; 27 | } 28 | 29 | #endif /* OVLB */ 30 | #ifdef OVL0 31 | 32 | boolean 33 | attacktype(ptr, atyp) 34 | register struct permonst *ptr; 35 | register int atyp; 36 | { 37 | int i; 38 | 39 | for(i = 0; i < NATTK; i++) 40 | if(ptr->mattk[i].aatyp == atyp) return(TRUE); 41 | 42 | return(FALSE); 43 | } 44 | 45 | #endif /* OVL0 */ 46 | #ifdef OVLB 47 | 48 | boolean 49 | poly_when_stoned(ptr) 50 | struct permonst *ptr; 51 | { 52 | return((boolean)(is_golem(ptr) && ptr != &mons[PM_STONE_GOLEM] && 53 | !(mvitals[PM_STONE_GOLEM].mvflags & G_GENOD))); 54 | /* allow G_EXTINCT */ 55 | } 56 | 57 | boolean 58 | resists_drli(mon) /* returns TRUE if monster is drain-life resistant */ 59 | struct monst *mon; 60 | { 61 | struct permonst *ptr = mon->data; 62 | struct obj *wep = ((mon == &youmonst) ? uwep : MON_WEP(mon)); 63 | 64 | return (boolean)(is_undead(ptr) || is_demon(ptr) || is_were(ptr) || 65 | ptr == &mons[PM_DEATH] || 66 | (wep && wep->oartifact && defends(AD_DRLI, wep))); 67 | } 68 | 69 | boolean 70 | resists_magm(mon) /* TRUE if monster is magic-missile resistant */ 71 | struct monst *mon; 72 | { 73 | struct permonst *ptr = mon->data; 74 | struct obj *o; 75 | 76 | /* as of 3.2.0: gray dragons, Angels, Oracle, Yeenoghu */ 77 | if (dmgtype(ptr, AD_MAGM) || ptr == &mons[PM_BABY_GRAY_DRAGON] || 78 | dmgtype(ptr, AD_RBRE)) /* Chromatic Dragon */ 79 | return TRUE; 80 | /* check for magic resistance granted by wielded weapon */ 81 | o = (mon == &youmonst) ? uwep : MON_WEP(mon); 82 | if (o && o->oartifact && defends(AD_MAGM, o)) 83 | return TRUE; 84 | /* check for magic resistance granted by worn or carried items */ 85 | o = (mon == &youmonst) ? invent : mon->minvent; 86 | for ( ; o; o = o->nobj) 87 | if ((o->owornmask && objects[o->otyp].oc_oprop == ANTIMAGIC) || 88 | (o->oartifact && protects(AD_MAGM, o))) 89 | return TRUE; 90 | return FALSE; 91 | } 92 | 93 | /* TRUE iff monster is resistant to light-induced blindness */ 94 | boolean 95 | resists_blnd(mon) 96 | struct monst *mon; 97 | { 98 | struct permonst *ptr = mon->data; 99 | boolean is_you = (mon == &youmonst); 100 | struct obj *o; 101 | 102 | if (is_you ? (Blind || u.usleep) : 103 | (mon->mblinded || !mon->mcansee || !haseyes(ptr) || 104 | /* BUG: temporary sleep sets mfrozen, but since 105 | paralysis does too, we can't check it */ 106 | mon->msleeping)) 107 | return TRUE; 108 | /* AD_BLND => yellow light, Archon, !cobra, !raven */ 109 | if (dmgtype(ptr, AD_BLND) && 110 | !attacktype(ptr, AT_SPIT) && !attacktype(ptr, AT_CLAW)) 111 | return TRUE; 112 | o = is_you ? uwep : MON_WEP(mon); 113 | if (o && o->oartifact && defends(AD_BLND, o)) 114 | return TRUE; 115 | o = is_you ? invent : mon->minvent; 116 | for ( ; o; o = o->nobj) 117 | if ((o->owornmask && objects[o->otyp].oc_oprop == BLINDED) || 118 | (o->oartifact && protects(AD_BLND, o))) 119 | return TRUE; 120 | return FALSE; 121 | } 122 | 123 | /* TRUE iff monster can be blinded by the given attack */ 124 | /* Note: may return TRUE when mdef is blind (e.g. new cream-pie attack) */ 125 | boolean 126 | can_blnd(magr, mdef, aatyp, obj) 127 | struct monst *magr; /* NULL == no specific aggressor */ 128 | struct monst *mdef; 129 | uchar aatyp; 130 | struct obj *obj; /* aatyp == AT_WEAP, AT_SPIT */ 131 | { 132 | boolean is_you = (mdef == &youmonst); 133 | boolean check_visor = FALSE; 134 | struct obj *o; 135 | const char *s; 136 | 137 | /* no eyes protect against all attacks for now */ 138 | if (!haseyes(mdef->data)) 139 | return FALSE; 140 | 141 | switch(aatyp) { 142 | case AT_EXPL: case AT_BOOM: case AT_GAZE: case AT_MAGC: 143 | case AT_BREA: /* assumed to be lightning */ 144 | /* light-based attacks may be cancelled or resisted */ 145 | if (magr && magr->mcan) 146 | return FALSE; 147 | return !resists_blnd(mdef); 148 | 149 | case AT_WEAP: case AT_SPIT: case AT_NONE: 150 | /* an object is used (thrown/spit/other) */ 151 | if (obj && (obj->otyp == CREAM_PIE)) { 152 | if (is_you && Blindfolded) 153 | return FALSE; 154 | } else if (obj && (obj->otyp == BLINDING_VENOM)) { 155 | /* all ublindf, including LENSES, protect, cream-pies too */ 156 | if (is_you && (ublindf || u.ucreamed)) 157 | return FALSE; 158 | check_visor = TRUE; 159 | } else if (obj && (obj->otyp == POT_BLINDNESS)) { 160 | return TRUE; /* no defense */ 161 | } else 162 | return FALSE; /* other objects cannot cause blindness yet */ 163 | if ((magr == &youmonst) && u.uswallow) 164 | return FALSE; /* can't affect eyes while inside monster */ 165 | break; 166 | 167 | case AT_ENGL: 168 | if (is_you && (Blindfolded || u.usleep || u.ucreamed)) 169 | return FALSE; 170 | if (!is_you && mdef->msleeping) 171 | return FALSE; 172 | break; 173 | 174 | case AT_CLAW: 175 | /* e.g. raven: all ublindf, including LENSES, protect */ 176 | if (is_you && ublindf) 177 | return FALSE; 178 | if ((magr == &youmonst) && u.uswallow) 179 | return FALSE; /* can't affect eyes while inside monster */ 180 | check_visor = TRUE; 181 | break; 182 | 183 | case AT_TUCH: case AT_STNG: 184 | /* some physical, blind-inducing attacks can be cancelled */ 185 | if (magr && magr->mcan) 186 | return FALSE; 187 | break; 188 | 189 | default: 190 | break; 191 | } 192 | 193 | /* check if wearing a visor (only checked if visor might help) */ 194 | if (check_visor) { 195 | o = (mdef == &youmonst) ? invent : mdef->minvent; 196 | for ( ; o; o = o->nobj) 197 | if ((o->owornmask & W_ARMH) && 198 | (s = OBJ_DESCR(objects[o->otyp])) != (char *)0 && 199 | !strcmp(s, "visored helmet")) 200 | return FALSE; 201 | } 202 | 203 | return TRUE; 204 | } 205 | 206 | #endif /* OVLB */ 207 | #ifdef OVL0 208 | 209 | boolean 210 | ranged_attk(ptr) /* returns TRUE if monster can attack at range */ 211 | struct permonst *ptr; 212 | { 213 | register int i, atyp; 214 | long atk_mask = (1L << AT_BREA) | (1L << AT_SPIT) | (1L << AT_GAZE); 215 | 216 | /* was: (attacktype(ptr, AT_BREA) || attacktype(ptr, AT_WEAP) || 217 | attacktype(ptr, AT_SPIT) || attacktype(ptr, AT_GAZE) || 218 | attacktype(ptr, AT_MAGC)); 219 | but that's too slow -dlc 220 | */ 221 | for (i = 0; i < NATTK; i++) { 222 | atyp = ptr->mattk[i].aatyp; 223 | if (atyp >= AT_WEAP) return TRUE; 224 | /* assert(atyp < 32); */ 225 | if ((atk_mask & (1L << atyp)) != 0L) return TRUE; 226 | } 227 | 228 | return FALSE; 229 | } 230 | 231 | boolean 232 | hates_silver(ptr) 233 | register struct permonst *ptr; 234 | /* returns TRUE if monster is especially affected by silver weapons */ 235 | { 236 | return((boolean)(is_were(ptr) || ptr->mlet==S_VAMPIRE || is_demon(ptr) || 237 | ptr == &mons[PM_SHADE] || 238 | (ptr->mlet==S_IMP && ptr != &mons[PM_TENGU]))); 239 | } 240 | 241 | #endif /* OVL0 */ 242 | #ifdef OVL1 243 | 244 | boolean 245 | can_track(ptr) /* returns TRUE if monster can track well */ 246 | register struct permonst *ptr; 247 | { 248 | if (uwep && uwep->oartifact == ART_EXCALIBUR) 249 | return TRUE; 250 | else 251 | return((boolean)haseyes(ptr)); 252 | } 253 | 254 | #endif /* OVL1 */ 255 | #ifdef OVLB 256 | 257 | boolean 258 | sliparm(ptr) /* creature will slide out of armor */ 259 | register struct permonst *ptr; 260 | { 261 | return((boolean)(is_whirly(ptr) || ptr->msize <= MZ_SMALL || 262 | noncorporeal(ptr))); 263 | } 264 | 265 | boolean 266 | breakarm(ptr) /* creature will break out of armor */ 267 | register struct permonst *ptr; 268 | { 269 | return ((bigmonst(ptr) || (ptr->msize > MZ_SMALL && !humanoid(ptr)) || 270 | /* special cases of humanoids that cannot wear body armor */ 271 | ptr == &mons[PM_MARILITH] || ptr == &mons[PM_WINGED_GARGOYLE]) 272 | && !sliparm(ptr)); 273 | } 274 | #endif /* OVLB */ 275 | #ifdef OVL1 276 | 277 | boolean 278 | sticks(ptr) /* creature sticks other creatures it hits */ 279 | register struct permonst *ptr; 280 | { 281 | return((boolean)(dmgtype(ptr,AD_STCK) || dmgtype(ptr,AD_WRAP) || 282 | attacktype(ptr,AT_HUGS))); 283 | } 284 | 285 | boolean 286 | dmgtype(ptr, dtyp) 287 | register struct permonst *ptr; 288 | register int dtyp; 289 | { 290 | int i; 291 | 292 | for(i = 0; i < NATTK; i++) 293 | if(ptr->mattk[i].adtyp == dtyp) return TRUE; 294 | 295 | return FALSE; 296 | } 297 | 298 | /* returns the maximum damage a defender can do to the attacker via 299 | * a passive defense */ 300 | int 301 | max_passive_dmg(mdef, magr) 302 | register struct monst *mdef, *magr; 303 | { 304 | int i, dmg = 0; 305 | uchar adtyp; 306 | 307 | for(i = 0; i < NATTK; i++) 308 | if(mdef->data->mattk[i].aatyp == AT_NONE || 309 | mdef->data->mattk[i].aatyp == AT_BOOM) { 310 | adtyp = mdef->data->mattk[i].adtyp; 311 | if ((adtyp == AD_ACID && !resists_acid(magr)) || 312 | (adtyp == AD_COLD && !resists_cold(magr)) || 313 | (adtyp == AD_FIRE && !resists_fire(magr)) || 314 | (adtyp == AD_ELEC && !resists_elec(magr)) || 315 | adtyp == AD_PHYS) { 316 | dmg = mdef->data->mattk[i].damn; 317 | if(!dmg) dmg = mdef->data->mlevel+1; 318 | dmg *= mdef->data->mattk[i].damd; 319 | } else dmg = 0; 320 | 321 | return dmg; 322 | } 323 | return 0; 324 | } 325 | 326 | #endif /* OVL1 */ 327 | #ifdef OVL0 328 | 329 | int 330 | monsndx(ptr) /* return an index into the mons array */ 331 | struct permonst *ptr; 332 | { 333 | register int i; 334 | 335 | i = (int)(ptr - &mons[0]); 336 | if (i < LOW_PM || i >= NUMMONS) { 337 | /* ought to switch this to use `fmt_ptr' */ 338 | panic("monsndx - could not index monster (%lx)", 339 | (unsigned long)ptr); 340 | return FALSE; /* will not get here */ 341 | } 342 | 343 | return(i); 344 | } 345 | 346 | #endif /* OVL0 */ 347 | #ifdef OVL1 348 | 349 | 350 | int 351 | name_to_mon(in_str) 352 | const char *in_str; 353 | { 354 | /* Be careful. We must check the entire string in case it was 355 | * something such as "ettin zombie corpse". The calling routine 356 | * doesn't know about the "corpse" until the monster name has 357 | * already been taken off the front, so we have to be able to 358 | * read the name with extraneous stuff such as "corpse" stuck on 359 | * the end. 360 | * This causes a problem for names which prefix other names such 361 | * as "ettin" on "ettin zombie". In this case we want the _longest_ 362 | * name which exists. 363 | * This also permits plurals created by adding suffixes such as 's' 364 | * or 'es'. Other plurals must still be handled explicitly. 365 | */ 366 | register int i; 367 | register int mntmp = NON_PM; 368 | register char *s, *str, *term; 369 | char buf[BUFSZ]; 370 | int len, slen; 371 | 372 | str = strcpy(buf, in_str); 373 | 374 | if (!strncmp(str, "a ", 2)) str += 2; 375 | else if (!strncmp(str, "an ", 3)) str += 3; 376 | 377 | slen = strlen(str); 378 | term = str + slen; 379 | 380 | if ((s = strstri(str, "vortices")) != 0) 381 | Strcpy(s+4, "ex"); 382 | /* be careful with "ies"; "priest", "zombies" */ 383 | else if (slen > 3 && !strcmpi(term-3, "ies") && 384 | (slen < 7 || strcmpi(term-7, "zombies"))) 385 | Strcpy(term-3, "y"); 386 | /* luckily no monster names end in fe or ve with ves plurals */ 387 | else if (slen > 3 && !strcmpi(term-3, "ves")) 388 | Strcpy(term-3, "f"); 389 | 390 | slen = strlen(str); /* length possibly needs recomputing */ 391 | 392 | { 393 | static const struct alt_spl { const char* name; short pm_val; } 394 | names[] = { 395 | /* Alternate spellings */ 396 | { "grey dragon", PM_GRAY_DRAGON }, 397 | { "baby grey dragon", PM_BABY_GRAY_DRAGON }, 398 | { "grey unicorn", PM_GRAY_UNICORN }, 399 | { "grey ooze", PM_GRAY_OOZE }, 400 | { "gray-elf", PM_GREY_ELF }, 401 | /* Hyphenated names */ 402 | { "ki rin", PM_KI_RIN }, 403 | { "uruk hai", PM_URUK_HAI }, 404 | { "orc captain", PM_ORC_CAPTAIN }, 405 | { "woodland elf", PM_WOODLAND_ELF }, 406 | { "green elf", PM_GREEN_ELF }, 407 | { "grey elf", PM_GREY_ELF }, 408 | { "gray elf", PM_GREY_ELF }, 409 | { "elf lord", PM_ELF_LORD }, 410 | #if 0 /* OBSOLETE */ 411 | { "high elf", PM_HIGH_ELF }, 412 | #endif 413 | { "olog hai", PM_OLOG_HAI }, 414 | { "arch lich", PM_ARCH_LICH }, 415 | /* Some irregular plurals */ 416 | { "incubi", PM_INCUBUS }, 417 | { "succubi", PM_SUCCUBUS }, 418 | { "violet fungi", PM_VIOLET_FUNGUS }, 419 | { "homunculi", PM_HOMUNCULUS }, 420 | { "baluchitheria", PM_BALUCHITHERIUM }, 421 | { "lurkers above", PM_LURKER_ABOVE }, 422 | { "cavemen", PM_CAVEMAN }, 423 | { "cavewomen", PM_CAVEWOMAN }, 424 | { "djinn", PM_DJINNI }, 425 | { "mumakil", PM_MUMAK }, 426 | { "erinyes", PM_ERINYS }, 427 | /* falsely caught by -ves check above */ 428 | { "master of thief", PM_MASTER_OF_THIEVES }, 429 | /* end of list */ 430 | { 0, 0 } 431 | }; 432 | register const struct alt_spl *namep; 433 | 434 | for (namep = names; namep->name; namep++) 435 | if (!strncmpi(str, namep->name, (int)strlen(namep->name))) 436 | return namep->pm_val; 437 | } 438 | 439 | for (len = 0, i = LOW_PM; i < NUMMONS; i++) { 440 | register int m_i_len = strlen(mons[i].mname); 441 | if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) { 442 | if (m_i_len == slen) return i; /* exact match */ 443 | else if (slen > m_i_len && 444 | (str[m_i_len] == ' ' || 445 | !strcmpi(&str[m_i_len], "s") || 446 | !strncmpi(&str[m_i_len], "s ", 2) || 447 | !strcmpi(&str[m_i_len], "es") || 448 | !strncmpi(&str[m_i_len], "es ", 3))) { 449 | mntmp = i; 450 | len = m_i_len; 451 | } 452 | } 453 | } 454 | if (mntmp == NON_PM) mntmp = title_to_mon(str, (int *)0, (int *)0); 455 | return mntmp; 456 | } 457 | 458 | #endif /* OVL1 */ 459 | #ifdef OVL2 460 | 461 | /* returns 3 values (0=male, 1=female, 2=none) */ 462 | int 463 | gender(mtmp) 464 | register struct monst *mtmp; 465 | { 466 | if (is_neuter(mtmp->data)) return 2; 467 | return mtmp->female; 468 | } 469 | 470 | /* Like gender(), but lower animals and such are still "it". */ 471 | /* This is the one we want to use when printing messages. */ 472 | int 473 | pronoun_gender(mtmp) 474 | register struct monst *mtmp; 475 | { 476 | if (!canspotmon(mtmp) || !humanoid(mtmp->data)) 477 | return 2; 478 | return mtmp->female; 479 | } 480 | 481 | #endif /* OVL2 */ 482 | #ifdef OVLB 483 | 484 | boolean 485 | levl_follower(mtmp) 486 | register struct monst *mtmp; 487 | { 488 | return((boolean)(mtmp->mtame || (mtmp->data->mflags2 & M2_STALK) || is_fshk(mtmp) 489 | || (mtmp->iswiz && !mon_has_amulet(mtmp)))); 490 | } 491 | 492 | static const short grownups[][2] = { 493 | {PM_CHICKATRICE, PM_COCKATRICE}, 494 | {PM_LITTLE_DOG, PM_DOG}, {PM_DOG, PM_LARGE_DOG}, 495 | {PM_HELL_HOUND_PUP, PM_HELL_HOUND}, 496 | {PM_WINTER_WOLF_CUB, PM_WINTER_WOLF}, 497 | {PM_KITTEN, PM_HOUSECAT}, {PM_HOUSECAT, PM_LARGE_CAT}, 498 | {PM_PONY, PM_HORSE}, {PM_HORSE, PM_WARHORSE}, 499 | {PM_KOBOLD, PM_LARGE_KOBOLD}, {PM_LARGE_KOBOLD, PM_KOBOLD_LORD}, 500 | {PM_GNOME, PM_GNOME_LORD}, {PM_GNOME_LORD, PM_GNOME_KING}, 501 | {PM_DWARF, PM_DWARF_LORD}, {PM_DWARF_LORD, PM_DWARF_KING}, 502 | {PM_OGRE, PM_OGRE_LORD}, {PM_OGRE_LORD, PM_OGRE_KING}, 503 | {PM_ELF, PM_ELF_LORD}, {PM_WOODLAND_ELF, PM_ELF_LORD}, 504 | {PM_GREEN_ELF, PM_ELF_LORD}, {PM_GREY_ELF, PM_ELF_LORD}, 505 | {PM_ELF_LORD, PM_ELVENKING}, 506 | {PM_LICH, PM_DEMILICH}, {PM_DEMILICH, PM_MASTER_LICH}, 507 | {PM_MASTER_LICH, PM_ARCH_LICH}, 508 | {PM_VAMPIRE, PM_VAMPIRE_LORD}, {PM_BAT, PM_GIANT_BAT}, 509 | {PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON}, 510 | {PM_BABY_SILVER_DRAGON, PM_SILVER_DRAGON}, 511 | #if 0 /* DEFERRED */ 512 | {PM_BABY_SHIMMERING_DRAGON, PM_SHIMMERING_DRAGON}, 513 | #endif 514 | {PM_BABY_RED_DRAGON, PM_RED_DRAGON}, 515 | {PM_BABY_WHITE_DRAGON, PM_WHITE_DRAGON}, 516 | {PM_BABY_ORANGE_DRAGON, PM_ORANGE_DRAGON}, 517 | {PM_BABY_BLACK_DRAGON, PM_BLACK_DRAGON}, 518 | {PM_BABY_BLUE_DRAGON, PM_BLUE_DRAGON}, 519 | {PM_BABY_GREEN_DRAGON, PM_GREEN_DRAGON}, 520 | {PM_BABY_YELLOW_DRAGON, PM_YELLOW_DRAGON}, 521 | {PM_RED_NAGA_HATCHLING, PM_RED_NAGA}, 522 | {PM_BLACK_NAGA_HATCHLING, PM_BLACK_NAGA}, 523 | {PM_GOLDEN_NAGA_HATCHLING, PM_GOLDEN_NAGA}, 524 | {PM_GUARDIAN_NAGA_HATCHLING, PM_GUARDIAN_NAGA}, 525 | {PM_SMALL_MIMIC, PM_LARGE_MIMIC}, {PM_LARGE_MIMIC, PM_GIANT_MIMIC}, 526 | {PM_BABY_LONG_WORM, PM_LONG_WORM}, 527 | {PM_BABY_PURPLE_WORM, PM_PURPLE_WORM}, 528 | {PM_BABY_CROCODILE, PM_CROCODILE}, 529 | {PM_SOLDIER, PM_SERGEANT}, 530 | {PM_SERGEANT, PM_LIEUTENANT}, 531 | {PM_LIEUTENANT, PM_CAPTAIN}, 532 | {PM_WATCHMAN, PM_WATCH_CAPTAIN}, 533 | {PM_ALIGNED_PRIEST, PM_HIGH_PRIEST}, 534 | {PM_STUDENT, PM_ARCHEOLOGIST}, 535 | {PM_ATTENDANT, PM_HEALER}, 536 | {PM_PAGE, PM_KNIGHT}, 537 | {PM_ACOLYTE, PM_PRIEST}, 538 | {PM_APPRENTICE, PM_WIZARD}, 539 | {PM_MANES,PM_LEMURE}, 540 | #ifdef KOPS 541 | {PM_KEYSTONE_KOP, PM_KOP_SERGEANT}, 542 | {PM_KOP_SERGEANT, PM_KOP_LIEUTENANT}, 543 | {PM_KOP_LIEUTENANT, PM_KOP_KAPTAIN}, 544 | #endif 545 | {NON_PM,NON_PM} 546 | }; 547 | 548 | int 549 | little_to_big(montype) 550 | int montype; 551 | { 552 | #ifndef AIXPS2_BUG 553 | register int i; 554 | 555 | for (i = 0; grownups[i][0] >= LOW_PM; i++) 556 | if(montype == grownups[i][0]) return grownups[i][1]; 557 | return montype; 558 | #else 559 | /* AIX PS/2 C-compiler 1.1.1 optimizer does not like the above for loop, 560 | * and causes segmentation faults at runtime. (The problem does not 561 | * occur if -O is not used.) 562 | * lehtonen@cs.Helsinki.FI (Tapio Lehtonen) 28031990 563 | */ 564 | int i; 565 | int monvalue; 566 | 567 | monvalue = montype; 568 | for (i = 0; grownups[i][0] >= LOW_PM; i++) 569 | if(montype == grownups[i][0]) monvalue = grownups[i][1]; 570 | 571 | return monvalue; 572 | #endif 573 | } 574 | 575 | int 576 | big_to_little(montype) 577 | int montype; 578 | { 579 | register int i; 580 | 581 | for (i = 0; grownups[i][0] >= LOW_PM; i++) 582 | if(montype == grownups[i][1]) return grownups[i][0]; 583 | return montype; 584 | } 585 | 586 | static const char *levitate[2] = { "float", "Float" }; 587 | static const char *fly[2] = { "fly", "Fly" }; 588 | static const char *slither[2] = { "slither", "Slither" }; 589 | static const char *ooze[2] = { "ooze", "Ooze" }; 590 | static const char *crawl[2] = { "crawl", "Crawl" }; 591 | 592 | const char * 593 | locomotion(ptr, def) 594 | const struct permonst *ptr; 595 | const char *def; 596 | { 597 | int capitalize = (*def == highc(*def)); 598 | 599 | return ( 600 | is_floater(ptr) ? levitate[capitalize] : 601 | is_flyer(ptr) ? fly[capitalize] : 602 | slithy(ptr) ? slither[capitalize] : 603 | amorphous(ptr) ? ooze[capitalize] : 604 | nolimbs(ptr) ? crawl[capitalize] : 605 | def 606 | ); 607 | 608 | } 609 | 610 | #endif /* OVLB */ 611 | 612 | /*mondata.c*/