1 | /* SCCS Id: @(#)makemon.c 3.3 2000/06/02 */ 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 "epri.h" 7 | #include "emin.h" 8 | #include "edog.h" 9 | #ifdef REINCARNATION 10 | #include <ctype.h> 11 | #endif 12 | 13 | STATIC_VAR NEARDATA struct monst zeromonst; 14 | 15 | #ifdef OVL0 16 | STATIC_DCL boolean FDECL(uncommon, (int)); 17 | STATIC_DCL int FDECL(align_shift, (struct permonst *)); 18 | #endif /* OVL0 */ 19 | STATIC_DCL boolean FDECL(wrong_elem_type, (struct permonst *)); 20 | STATIC_DCL void FDECL(m_initgrp,(struct monst *,int,int,int)); 21 | STATIC_DCL void FDECL(m_initthrow,(struct monst *,int,int)); 22 | STATIC_DCL void FDECL(m_initweap,(struct monst *)); 23 | #ifdef OVL1 24 | STATIC_DCL void FDECL(m_initinv,(struct monst *)); 25 | #endif /* OVL1 */ 26 | 27 | extern const int monstr[]; 28 | 29 | #define m_initsgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 3) 30 | #define m_initlgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 10) 31 | #define toostrong(monindx, lev) (monstr[monindx] > lev) 32 | #define tooweak(monindx, lev) (monstr[monindx] < lev) 33 | 34 | #ifdef OVLB 35 | boolean 36 | is_home_elemental(ptr) 37 | register struct permonst *ptr; 38 | { 39 | if (ptr->mlet == S_ELEMENTAL) 40 | switch (monsndx(ptr)) { 41 | case PM_AIR_ELEMENTAL: return Is_airlevel(&u.uz); 42 | case PM_FIRE_ELEMENTAL: return Is_firelevel(&u.uz); 43 | case PM_EARTH_ELEMENTAL: return Is_earthlevel(&u.uz); 44 | case PM_WATER_ELEMENTAL: return Is_waterlevel(&u.uz); 45 | } 46 | return FALSE; 47 | } 48 | 49 | /* 50 | * Return true if the given monster cannot exist on this elemental level. 51 | */ 52 | STATIC_OVL boolean 53 | wrong_elem_type(ptr) 54 | register struct permonst *ptr; 55 | { 56 | if (ptr->mlet == S_ELEMENTAL) { 57 | return((boolean)(!is_home_elemental(ptr))); 58 | } else if (Is_earthlevel(&u.uz)) { 59 | /* no restrictions? */ 60 | } else if (Is_waterlevel(&u.uz)) { 61 | /* just monsters that can swim */ 62 | if(!is_swimmer(ptr)) return TRUE; 63 | } else if (Is_firelevel(&u.uz)) { 64 | if (!pm_resistance(ptr,MR_FIRE)) return TRUE; 65 | } else if (Is_airlevel(&u.uz)) { 66 | if(!(is_flyer(ptr) && ptr->mlet != S_TRAPPER) && !is_floater(ptr) 67 | && !amorphous(ptr) && !noncorporeal(ptr) && !is_whirly(ptr)) 68 | return TRUE; 69 | } 70 | return FALSE; 71 | } 72 | 73 | STATIC_OVL void 74 | m_initgrp(mtmp, x, y, n) /* make a group just like mtmp */ 75 | register struct monst *mtmp; 76 | register int x, y, n; 77 | { 78 | coord mm; 79 | register int cnt = rnd(n); 80 | struct monst *mon; 81 | #if defined(__GNUC__) && (defined(HPUX) || defined(DGUX)) 82 | /* There is an unresolved problem with several people finding that 83 | * the game hangs eating CPU; if interrupted and restored, the level 84 | * will be filled with monsters. Of those reports giving system type, 85 | * there were two DG/UX and two HP-UX, all using gcc as the compiler. 86 | * hcroft@hpopb1.cern.ch, using gcc 2.6.3 on HP-UX, says that the 87 | * problem went away for him and another reporter-to-newsgroup 88 | * after adding this debugging code. This has almost got to be a 89 | * compiler bug, but until somebody tracks it down and gets it fixed, 90 | * might as well go with the "but it went away when I tried to find 91 | * it" code. 92 | */ 93 | int cnttmp,cntdiv; 94 | 95 | cnttmp = cnt; 96 | # ifdef DEBUG 97 | pline("init group call x=%d,y=%d,n=%d,cnt=%d.", x, y, n, cnt); 98 | # endif 99 | cntdiv = ((u.ulevel < 3) ? 4 : (u.ulevel < 5) ? 2 : 1); 100 | #endif 101 | /* Tuning: cut down on swarming at low character levels [mrs] */ 102 | cnt /= (u.ulevel < 3) ? 4 : (u.ulevel < 5) ? 2 : 1; 103 | #if defined(__GNUC__) && (defined(HPUX) || defined(DGUX)) 104 | if (cnt != (cnttmp/cntdiv)) { 105 | pline("cnt=%d using %d, cnttmp=%d, cntdiv=%d", cnt, 106 | (u.ulevel < 3) ? 4 : (u.ulevel < 5) ? 2 : 1, 107 | cnttmp, cntdiv); 108 | } 109 | #endif 110 | if(!cnt) cnt++; 111 | #if defined(__GNUC__) && (defined(HPUX) || defined(DGUX)) 112 | if (cnt < 0) cnt = 1; 113 | if (cnt > 10) cnt = 10; 114 | #endif 115 | 116 | mm.x = x; 117 | mm.y = y; 118 | while(cnt--) { 119 | if (peace_minded(mtmp->data)) continue; 120 | /* Don't create groups of peaceful monsters since they'll get 121 | * in our way. If the monster has a percentage chance so some 122 | * are peaceful and some are not, the result will just be a 123 | * smaller group. 124 | */ 125 | if (enexto(&mm, mm.x, mm.y, mtmp->data)) { 126 | mon = makemon(mtmp->data, mm.x, mm.y, NO_MM_FLAGS); 127 | mon->mpeaceful = FALSE; 128 | set_malign(mon); 129 | /* Undo the second peace_minded() check in makemon(); if the 130 | * monster turned out to be peaceful the first time we 131 | * didn't create it at all; we don't want a second check. 132 | */ 133 | } 134 | } 135 | } 136 | 137 | STATIC_OVL 138 | void 139 | m_initthrow(mtmp,otyp,oquan) 140 | struct monst *mtmp; 141 | int otyp,oquan; 142 | { 143 | register struct obj *otmp; 144 | 145 | otmp = mksobj(otyp, TRUE, FALSE); 146 | otmp->quan = (long) rn1(oquan, 3); 147 | otmp->owt = weight(otmp); 148 | if (otyp == ORCISH_ARROW) otmp->opoisoned = TRUE; 149 | (void) mpickobj(mtmp, otmp); 150 | } 151 | 152 | #endif /* OVLB */ 153 | #ifdef OVL2 154 | 155 | STATIC_OVL void 156 | m_initweap(mtmp) 157 | register struct monst *mtmp; 158 | { 159 | register struct permonst *ptr = mtmp->data; 160 | register int mm = monsndx(ptr); 161 | struct obj *otmp; 162 | 163 | #ifdef REINCARNATION 164 | if (Is_rogue_level(&u.uz)) return; 165 | #endif 166 | /* 167 | * first a few special cases: 168 | * 169 | * giants get a boulder to throw sometimes. 170 | * ettins get clubs 171 | * kobolds get darts to throw 172 | * centaurs get some sort of bow & arrows or bolts 173 | * soldiers get all sorts of things. 174 | * kops get clubs & cream pies. 175 | */ 176 | switch (ptr->mlet) { 177 | case S_GIANT: 178 | if (rn2(2)) (void)mongets(mtmp, (mm != PM_ETTIN) ? 179 | BOULDER : CLUB); 180 | break; 181 | case S_HUMAN: 182 | if(is_mercenary(ptr)) { 183 | int w1 = 0, w2 = 0; 184 | switch (mm) { 185 | 186 | case PM_WATCHMAN: 187 | case PM_SOLDIER: 188 | if (!rn2(3)) { 189 | w1 = rn1(BEC_DE_CORBIN - PARTISAN + 1, PARTISAN); 190 | w2 = rn2(2) ? DAGGER : KNIFE; 191 | } else w1 = rn2(2) ? SPEAR : SHORT_SWORD; 192 | break; 193 | case PM_SERGEANT: 194 | w1 = rn2(2) ? FLAIL : MACE; 195 | break; 196 | case PM_LIEUTENANT: 197 | w1 = rn2(2) ? BROADSWORD : LONG_SWORD; 198 | break; 199 | case PM_CAPTAIN: 200 | case PM_WATCH_CAPTAIN: 201 | w1 = rn2(2) ? LONG_SWORD : SILVER_SABER; 202 | break; 203 | default: 204 | if (!rn2(4)) w1 = DAGGER; 205 | if (!rn2(7)) w2 = SPEAR; 206 | break; 207 | } 208 | if (w1) (void)mongets(mtmp, w1); 209 | if (!w2 && w1 != DAGGER && !rn2(4)) w2 = KNIFE; 210 | if (w2) (void)mongets(mtmp, w2); 211 | } else if (is_elf(ptr)) { 212 | if (rn2(2)) 213 | (void) mongets(mtmp, 214 | rn2(2) ? ELVEN_MITHRIL_COAT : ELVEN_CLOAK); 215 | if (rn2(2)) (void)mongets(mtmp, ELVEN_LEATHER_HELM); 216 | else if (!rn2(4)) (void)mongets(mtmp, ELVEN_BOOTS); 217 | if (rn2(2)) (void)mongets(mtmp, ELVEN_DAGGER); 218 | switch (rn2(3)) { 219 | case 0: 220 | if (!rn2(4)) (void)mongets(mtmp, ELVEN_SHIELD); 221 | if (rn2(3)) (void)mongets(mtmp, ELVEN_SHORT_SWORD); 222 | (void)mongets(mtmp, ELVEN_BOW); 223 | m_initthrow(mtmp, ELVEN_ARROW, 12); 224 | break; 225 | case 1: 226 | (void)mongets(mtmp, ELVEN_BROADSWORD); 227 | if (rn2(2)) (void)mongets(mtmp, ELVEN_SHIELD); 228 | break; 229 | case 2: 230 | if (rn2(2)) { 231 | (void)mongets(mtmp, ELVEN_SPEAR); 232 | (void)mongets(mtmp, ELVEN_SHIELD); 233 | } 234 | break; 235 | } 236 | if (mm == PM_ELVENKING) { 237 | if (rn2(3) || (in_mklev && Is_earthlevel(&u.uz))) 238 | (void)mongets(mtmp, PICK_AXE); 239 | if (!rn2(50)) (void)mongets(mtmp, CRYSTAL_BALL); 240 | } 241 | } else if (ptr->msound == MS_PRIEST) { 242 | otmp = mksobj(MACE, FALSE, FALSE); 243 | if(otmp) { 244 | otmp->spe = rnd(3); 245 | if(!rn2(2)) curse(otmp); 246 | (void) mpickobj(mtmp, otmp); 247 | } 248 | } 249 | break; 250 | 251 | case S_ANGEL: 252 | { 253 | int spe2; 254 | 255 | /* create minion stuff; can't use mongets */ 256 | otmp = mksobj(LONG_SWORD, FALSE, FALSE); 257 | 258 | /* maybe make it special */ 259 | if (!rn2(20) || is_lord(ptr)) 260 | otmp = oname(otmp, artiname( 261 | rn2(2) ? ART_DEMONBANE : ART_SUNSWORD)); 262 | bless(otmp); 263 | otmp->oerodeproof = TRUE; 264 | spe2 = rn2(4); 265 | otmp->spe = max(otmp->spe, spe2); 266 | (void) mpickobj(mtmp, otmp); 267 | 268 | otmp = mksobj(!rn2(4) || is_lord(ptr) ? 269 | SHIELD_OF_REFLECTION : LARGE_SHIELD, 270 | FALSE, FALSE); 271 | otmp->cursed = FALSE; 272 | otmp->oerodeproof = TRUE; 273 | otmp->spe = 0; 274 | (void) mpickobj(mtmp, otmp); 275 | } 276 | break; 277 | 278 | case S_HUMANOID: 279 | if (mm == PM_HOBBIT) { 280 | switch (rn2(3)) { 281 | case 0: 282 | (void)mongets(mtmp, DAGGER); 283 | break; 284 | case 1: 285 | (void)mongets(mtmp, ELVEN_DAGGER); 286 | break; 287 | case 2: 288 | (void)mongets(mtmp, SLING); 289 | break; 290 | } 291 | if (!rn2(10)) (void)mongets(mtmp, ELVEN_MITHRIL_COAT); 292 | if (!rn2(10)) (void)mongets(mtmp, DWARVISH_CLOAK); 293 | } else if (is_dwarf(ptr)) { 294 | if (rn2(7)) (void)mongets(mtmp, DWARVISH_CLOAK); 295 | if (rn2(7)) (void)mongets(mtmp, IRON_SHOES); 296 | if (!rn2(4)) { 297 | (void)mongets(mtmp, DWARVISH_SHORT_SWORD); 298 | /* note: you can't use a mattock with a shield */ 299 | if (rn2(2)) (void)mongets(mtmp, DWARVISH_MATTOCK); 300 | else { 301 | (void)mongets(mtmp, AXE); 302 | (void)mongets(mtmp, DWARVISH_ROUNDSHIELD); 303 | } 304 | (void)mongets(mtmp, DWARVISH_IRON_HELM); 305 | if (!rn2(3)) 306 | (void)mongets(mtmp, DWARVISH_MITHRIL_COAT); 307 | } else { 308 | (void)mongets(mtmp, !rn2(3) ? PICK_AXE : DAGGER); 309 | } 310 | } 311 | break; 312 | # ifdef KOPS 313 | case S_KOP: /* create Keystone Kops with cream pies to 314 | * throw. As suggested by KAA. [MRS] 315 | */ 316 | if (!rn2(4)) m_initthrow(mtmp, CREAM_PIE, 2); 317 | if (!rn2(3)) (void)mongets(mtmp,(rn2(2)) ? CLUB : RUBBER_HOSE); 318 | break; 319 | # endif 320 | case S_ORC: 321 | if(rn2(2)) (void)mongets(mtmp, ORCISH_HELM); 322 | switch (mm != PM_ORC_CAPTAIN ? mm : 323 | rn2(2) ? PM_MORDOR_ORC : PM_URUK_HAI) { 324 | case PM_MORDOR_ORC: 325 | if(!rn2(3)) (void)mongets(mtmp, SCIMITAR); 326 | if(!rn2(3)) (void)mongets(mtmp, ORCISH_SHIELD); 327 | if(!rn2(3)) (void)mongets(mtmp, KNIFE); 328 | if(!rn2(3)) (void)mongets(mtmp, ORCISH_CHAIN_MAIL); 329 | break; 330 | case PM_URUK_HAI: 331 | if(!rn2(3)) (void)mongets(mtmp, ORCISH_CLOAK); 332 | if(!rn2(3)) (void)mongets(mtmp, ORCISH_SHORT_SWORD); 333 | if(!rn2(3)) (void)mongets(mtmp, IRON_SHOES); 334 | if(!rn2(3)) { 335 | (void)mongets(mtmp, ORCISH_BOW); 336 | m_initthrow(mtmp, ORCISH_ARROW, 12); 337 | } 338 | if(!rn2(3)) (void)mongets(mtmp, URUK_HAI_SHIELD); 339 | break; 340 | default: 341 | if (mm != PM_ORC_SHAMAN && rn2(2)) 342 | (void)mongets(mtmp, (mm == PM_GOBLIN || rn2(2) == 0) 343 | ? ORCISH_DAGGER : SCIMITAR); 344 | } 345 | break; 346 | case S_OGRE: 347 | if (!rn2(mm == PM_OGRE_KING ? 3 : mm == PM_OGRE_LORD ? 6 : 12)) 348 | (void) mongets(mtmp, BATTLE_AXE); 349 | else 350 | (void) mongets(mtmp, CLUB); 351 | break; 352 | case S_TROLL: 353 | if (!rn2(2)) switch (rn2(4)) { 354 | case 0: (void)mongets(mtmp, RANSEUR); break; 355 | case 1: (void)mongets(mtmp, PARTISAN); break; 356 | case 2: (void)mongets(mtmp, GLAIVE); break; 357 | case 3: (void)mongets(mtmp, SPETUM); break; 358 | } 359 | break; 360 | case S_KOBOLD: 361 | if (!rn2(4)) m_initthrow(mtmp, DART, 12); 362 | break; 363 | 364 | case S_CENTAUR: 365 | if (rn2(2)) { 366 | if(ptr == &mons[PM_FOREST_CENTAUR]) { 367 | (void)mongets(mtmp, BOW); 368 | m_initthrow(mtmp, ARROW, 12); 369 | } else { 370 | (void)mongets(mtmp, CROSSBOW); 371 | m_initthrow(mtmp, CROSSBOW_BOLT, 12); 372 | } 373 | } 374 | break; 375 | case S_WRAITH: 376 | (void)mongets(mtmp, KNIFE); 377 | (void)mongets(mtmp, LONG_SWORD); 378 | break; 379 | case S_ZOMBIE: 380 | if (!rn2(4)) (void)mongets(mtmp, LEATHER_ARMOR); 381 | if (!rn2(4)) 382 | (void)mongets(mtmp, (rn2(3) ? KNIFE : SHORT_SWORD)); 383 | break; 384 | case S_LIZARD: 385 | if (mm == PM_SALAMANDER) 386 | (void)mongets(mtmp, (rn2(7) ? SPEAR : rn2(3) ? 387 | TRIDENT : STILETTO)); 388 | break; 389 | case S_DEMON: 390 | switch (mm) { 391 | case PM_BALROG: 392 | (void)mongets(mtmp, BULLWHIP); 393 | (void)mongets(mtmp, BROADSWORD); 394 | break; 395 | case PM_ORCUS: 396 | (void)mongets(mtmp, WAN_DEATH); /* the Wand of Orcus */ 397 | break; 398 | case PM_HORNED_DEVIL: 399 | (void)mongets(mtmp, rn2(4) ? TRIDENT : BULLWHIP); 400 | break; 401 | case PM_ICE_DEVIL: 402 | if (!rn2(4)) (void)mongets(mtmp, SPEAR); 403 | break; 404 | case PM_ASMODEUS: 405 | (void)mongets(mtmp, WAN_COLD); 406 | (void)mongets(mtmp, WAN_FIRE); 407 | break; 408 | case PM_DISPATER: 409 | (void)mongets(mtmp, WAN_STRIKING); 410 | break; 411 | case PM_YEENOGHU: 412 | (void)mongets(mtmp, FLAIL); 413 | break; 414 | } 415 | /* prevent djinnis and mail daemons from leaving objects when 416 | * they vanish 417 | */ 418 | if (!is_demon(ptr)) break; 419 | /* fall thru */ 420 | /* 421 | * Now the general case, Some chance of getting some type 422 | * of weapon for "normal" monsters. Certain special types 423 | * of monsters will get a bonus chance or different selections. 424 | */ 425 | default: 426 | { 427 | int bias; 428 | 429 | bias = is_lord(ptr) + is_prince(ptr) * 2 + extra_nasty(ptr); 430 | switch(rnd(14 - (2 * bias))) { 431 | case 1: 432 | if(strongmonst(ptr)) (void) mongets(mtmp, BATTLE_AXE); 433 | else m_initthrow(mtmp, DART, 12); 434 | break; 435 | case 2: 436 | if(strongmonst(ptr)) 437 | (void) mongets(mtmp, TWO_HANDED_SWORD); 438 | else { 439 | (void) mongets(mtmp, CROSSBOW); 440 | m_initthrow(mtmp, CROSSBOW_BOLT, 12); 441 | } 442 | break; 443 | case 3: 444 | (void) mongets(mtmp, BOW); 445 | m_initthrow(mtmp, ARROW, 12); 446 | break; 447 | case 4: 448 | if(strongmonst(ptr)) (void) mongets(mtmp, LONG_SWORD); 449 | else m_initthrow(mtmp, DAGGER, 3); 450 | break; 451 | case 5: 452 | if(strongmonst(ptr)) 453 | (void) mongets(mtmp, LUCERN_HAMMER); 454 | else (void) mongets(mtmp, AKLYS); 455 | break; 456 | default: 457 | break; 458 | } 459 | } 460 | break; 461 | } 462 | if ((int) mtmp->m_lev > rn2(75)) 463 | (void) mongets(mtmp, rnd_offensive_item(mtmp)); 464 | } 465 | 466 | #endif /* OVL2 */ 467 | #ifdef OVL1 468 | 469 | STATIC_OVL void 470 | m_initinv(mtmp) 471 | register struct monst *mtmp; 472 | { 473 | register int cnt; 474 | register struct obj *otmp; 475 | register struct permonst *ptr = mtmp->data; 476 | #ifdef REINCARNATION 477 | if (Is_rogue_level(&u.uz)) return; 478 | #endif 479 | /* 480 | * Soldiers get armour & rations - armour approximates their ac. 481 | * Nymphs may get mirror or potion of object detection. 482 | */ 483 | switch(ptr->mlet) { 484 | 485 | case S_HUMAN: 486 | if(is_mercenary(ptr)) { 487 | register int mac; 488 | 489 | switch(monsndx(ptr)) { 490 | case PM_GUARD: mac = -1; break; 491 | case PM_SOLDIER: mac = 3; break; 492 | case PM_SERGEANT: mac = 0; break; 493 | case PM_LIEUTENANT: mac = -2; break; 494 | case PM_CAPTAIN: mac = -3; break; 495 | case PM_WATCHMAN: mac = 3; break; 496 | case PM_WATCH_CAPTAIN: mac = -2; break; 497 | default: impossible("odd mercenary %d?", monsndx(ptr)); 498 | mac = 0; 499 | break; 500 | } 501 | 502 | if (mac < -1 && rn2(5)) 503 | mac += 7 + mongets(mtmp, (rn2(5)) ? 504 | PLATE_MAIL : CRYSTAL_PLATE_MAIL); 505 | else if (mac < 3 && rn2(5)) 506 | mac += 6 + mongets(mtmp, (rn2(3)) ? 507 | SPLINT_MAIL : BANDED_MAIL); 508 | else if (rn2(5)) 509 | mac += 3 + mongets(mtmp, (rn2(3)) ? 510 | RING_MAIL : STUDDED_LEATHER_ARMOR); 511 | else 512 | mac += 2 + mongets(mtmp, LEATHER_ARMOR); 513 | 514 | if (mac < 10 && rn2(3)) 515 | mac += 1 + mongets(mtmp, HELMET); 516 | else if (mac < 10 && rn2(2)) 517 | mac += 1 + mongets(mtmp, DENTED_POT); 518 | if (mac < 10 && rn2(3)) 519 | mac += 1 + mongets(mtmp, SMALL_SHIELD); 520 | else if (mac < 10 && rn2(2)) 521 | mac += 2 + mongets(mtmp, LARGE_SHIELD); 522 | if (mac < 10 && rn2(3)) 523 | mac += 1 + mongets(mtmp, LOW_BOOTS); 524 | else if (mac < 10 && rn2(2)) 525 | mac += 2 + mongets(mtmp, HIGH_BOOTS); 526 | if (mac < 10 && rn2(3)) 527 | mac += 1 + mongets(mtmp, LEATHER_GLOVES); 528 | else if (mac < 10 && rn2(2)) 529 | mac += 1 + mongets(mtmp, ELVEN_CLOAK); 530 | 531 | if(ptr != &mons[PM_GUARD] && 532 | ptr != &mons[PM_WATCHMAN] && 533 | ptr != &mons[PM_WATCH_CAPTAIN]) { 534 | if (!rn2(3)) (void) mongets(mtmp, K_RATION); 535 | if (!rn2(2)) (void) mongets(mtmp, C_RATION); 536 | if (ptr != &mons[PM_SOLDIER] && !rn2(3)) 537 | (void) mongets(mtmp, BUGLE); 538 | } else 539 | if (ptr == &mons[PM_WATCHMAN] && rn2(3)) 540 | (void) mongets(mtmp, TIN_WHISTLE); 541 | } else if (ptr == &mons[PM_SHOPKEEPER]) { 542 | (void) mongets(mtmp,SKELETON_KEY); 543 | switch (rn2(4)) { 544 | /* MAJOR fall through ... */ 545 | case 0: (void) mongets(mtmp, WAN_MAGIC_MISSILE); 546 | case 1: (void) mongets(mtmp, POT_EXTRA_HEALING); 547 | case 2: (void) mongets(mtmp, POT_HEALING); 548 | case 3: (void) mongets(mtmp, WAN_STRIKING); 549 | } 550 | } else if (ptr->msound == MS_PRIEST) { 551 | (void) mongets(mtmp, ROBE); 552 | (void) mongets(mtmp, SMALL_SHIELD); 553 | mtmp->mgold = (long)rn1(10,20); 554 | } 555 | break; 556 | case S_NYMPH: 557 | if(!rn2(2)) (void) mongets(mtmp, MIRROR); 558 | if(!rn2(2)) (void) mongets(mtmp, POT_OBJECT_DETECTION); 559 | break; 560 | case S_GIANT: 561 | if (ptr == &mons[PM_MINOTAUR]) { 562 | if (!rn2(3) || (in_mklev && Is_earthlevel(&u.uz))) 563 | (void) mongets(mtmp, WAN_DIGGING); 564 | } else if (is_giant(ptr)) { 565 | for (cnt = rn2((int)(mtmp->m_lev / 2)); cnt; cnt--) { 566 | otmp = mksobj(rnd_class(DILITHIUM_CRYSTAL,LUCKSTONE-1), 567 | FALSE, FALSE); 568 | otmp->quan = (long) rn1(2, 3); 569 | otmp->owt = weight(otmp); 570 | (void) mpickobj(mtmp, otmp); 571 | } 572 | } 573 | break; 574 | case S_WRAITH: 575 | if (ptr == &mons[PM_NAZGUL]) { 576 | otmp = mksobj(RIN_INVISIBILITY, FALSE, FALSE); 577 | curse(otmp); 578 | (void) mpickobj(mtmp, otmp); 579 | } 580 | break; 581 | case S_LICH: 582 | if (ptr == &mons[PM_MASTER_LICH] && !rn2(13)) 583 | (void)mongets(mtmp, (rn2(7) ? ATHAME : WAN_NOTHING)); 584 | else if (ptr == &mons[PM_ARCH_LICH] && !rn2(3)) { 585 | otmp = mksobj(rn2(3) ? ATHAME : QUARTERSTAFF, 586 | TRUE, rn2(13) ? FALSE : TRUE); 587 | if (otmp->spe < 2) otmp->spe = rnd(3); 588 | if (!rn2(4)) otmp->oerodeproof = 1; 589 | (void) mpickobj(mtmp, otmp); 590 | } 591 | break; 592 | case S_MUMMY: 593 | if (rn2(7)) (void)mongets(mtmp, MUMMY_WRAPPING); 594 | break; 595 | case S_QUANTMECH: 596 | if (!rn2(20)) { 597 | otmp = mksobj(LARGE_BOX, FALSE, FALSE); 598 | otmp->spe = 1; /* flag for special box */ 599 | otmp->owt = weight(otmp); 600 | (void) mpickobj(mtmp, otmp); 601 | } 602 | break; 603 | case S_LEPRECHAUN: 604 | mtmp->mgold = (long) d(level_difficulty(), 30); 605 | break; 606 | default: 607 | break; 608 | } 609 | 610 | /* ordinary soldiers rarely have access to magic (or gold :-) */ 611 | if (ptr == &mons[PM_SOLDIER] && rn2(13)) return; 612 | 613 | if ((int) mtmp->m_lev > rn2(50)) 614 | (void) mongets(mtmp, rnd_defensive_item(mtmp)); 615 | if ((int) mtmp->m_lev > rn2(100)) 616 | (void) mongets(mtmp, rnd_misc_item(mtmp)); 617 | if (likes_gold(ptr) && !mtmp->mgold && !rn2(5)) 618 | mtmp->mgold = 619 | (long) d(level_difficulty(), mtmp->minvent ? 5 : 10); 620 | } 621 | 622 | struct monst * 623 | clone_mon(mon) 624 | struct monst *mon; 625 | { 626 | coord mm; 627 | struct monst *m2; 628 | 629 | /* may be too weak or have been extinguished for population control */ 630 | if (mon->mhp <= 1 || (mvitals[monsndx(mon->data)].mvflags & G_EXTINCT)) 631 | return (struct monst *)0; 632 | 633 | mm.x = mon->mx; 634 | mm.y = mon->my; 635 | if (!enexto(&mm, mm.x, mm.y, mon->data) || MON_AT(mm.x, mm.y)) 636 | return (struct monst *)0; 637 | m2 = newmonst(0); 638 | *m2 = *mon; /* copy condition of old monster */ 639 | m2->nmon = fmon; 640 | fmon = m2; 641 | m2->m_id = flags.ident++; 642 | if (!m2->m_id) m2->m_id = flags.ident++; /* ident overflowed */ 643 | m2->mx = mm.x; 644 | m2->my = mm.y; 645 | 646 | m2->minvent = (struct obj *) 0; /* objects don't clone */ 647 | m2->mleashed = FALSE; 648 | m2->mgold = 0L; 649 | /* Max HP the same, but current HP halved for both. The caller 650 | * might want to override this by halving the max HP also. 651 | * When current HP is odd, the original keeps the extra point. 652 | */ 653 | m2->mhpmax = mon->mhpmax; 654 | m2->mhp = mon->mhp / 2; 655 | mon->mhp -= m2->mhp; 656 | 657 | /* since shopkeepers and guards will only be cloned if they've been 658 | * polymorphed away from their original forms, the clone doesn't have 659 | * room for the extra information. we also don't want two shopkeepers 660 | * around for the same shop. 661 | * similarly, clones of named monsters don't have room for the name, 662 | * so we just make the clone unnamed instead of bothering to create 663 | * a clone with room and copying over the name from the right place 664 | * (which changes if the original was a shopkeeper or guard). 665 | */ 666 | if (mon->isshk) m2->isshk = FALSE; 667 | if (mon->isgd) m2->isgd = FALSE; 668 | if (mon->ispriest) m2->ispriest = FALSE; 669 | m2->mxlth = 0; 670 | m2->mnamelth = 0; 671 | place_monster(m2, m2->mx, m2->my); 672 | if (emits_light(m2->data)) 673 | new_light_source(m2->mx, m2->my, emits_light(m2->data), 674 | LS_MONSTER, (genericptr_t)m2); 675 | newsym(m2->mx,m2->my); /* display the new monster */ 676 | if (mon->mtame) { 677 | struct monst *m3; 678 | 679 | /* because m2 is a copy of mon it is tame but not init'ed. 680 | * however, tamedog will not re-tame a tame dog, so m2 681 | * must be made non-tame to get initialized properly. 682 | */ 683 | m2->mtame = 0; 684 | if ((m3 = tamedog(m2, (struct obj *)0)) != 0) 685 | m2 = m3; 686 | } 687 | return m2; 688 | } 689 | 690 | /* 691 | * called with [x,y] = coordinates; 692 | * [0,0] means anyplace 693 | * [u.ux,u.uy] means: near player (if !in_mklev) 694 | * 695 | * In case we make a monster group, only return the one at [x,y]. 696 | */ 697 | struct monst * 698 | makemon(ptr, x, y, mmflags) 699 | register struct permonst *ptr; 700 | register int x, y; 701 | register int mmflags; 702 | { 703 | register struct monst *mtmp; 704 | int mndx, mcham, ct, mitem, xlth; 705 | boolean anymon = (!ptr); 706 | boolean byyou = (x == u.ux && y == u.uy); 707 | boolean allow_minvent = ((mmflags & NO_MINVENT) == 0); 708 | uchar lim; 709 | 710 | /* if caller wants random location, do it here */ 711 | if(x == 0 && y == 0) { 712 | int tryct = 0; /* careful with bigrooms */ 713 | struct monst fakemon; 714 | 715 | fakemon.data = ptr; /* set up for goodpos */ 716 | do { 717 | x = rn1(COLNO-3,2); 718 | y = rn2(ROWNO); 719 | } while(!goodpos(x, y, ptr ? &fakemon : (struct monst *)0) || 720 | (!in_mklev && tryct++ < 50 && cansee(x, y))); 721 | } else if (byyou && !in_mklev) { 722 | coord bypos; 723 | 724 | if(enexto(&bypos, u.ux, u.uy, ptr)) { 725 | x = bypos.x; 726 | y = bypos.y; 727 | } else 728 | return((struct monst *)0); 729 | } 730 | 731 | /* if a monster already exists at the position, return */ 732 | if(MON_AT(x, y)) 733 | return((struct monst *) 0); 734 | 735 | if(ptr){ 736 | mndx = monsndx(ptr); 737 | /* if you are to make a specific monster and it has 738 | already been genocided, return */ 739 | if (mvitals[mndx].mvflags & G_GENOD) return((struct monst *) 0); 740 | #ifdef DEBUG 741 | if (wizard && (mvitals[mndx].mvflags & G_EXTINCT)) 742 | pline("Explicitly creating extinct monster %s.", 743 | mons[mndx].mname); 744 | #endif 745 | } else { 746 | /* make a random (common) monster that can survive here. 747 | * (the special levels ask for random monsters at specific 748 | * positions, causing mass drowning on the medusa level, 749 | * for instance.) 750 | */ 751 | int tryct = 0; /* maybe there are no good choices */ 752 | struct monst fakemon; 753 | do { 754 | if(!(ptr = rndmonst())) { 755 | #ifdef DEBUG 756 | pline("Warning: no monster."); 757 | #endif 758 | return((struct monst *) 0); /* no more monsters! */ 759 | } 760 | fakemon.data = ptr; /* set up for goodpos */ 761 | } while(!goodpos(x, y, &fakemon) && tryct++ < 50); 762 | mndx = monsndx(ptr); 763 | } 764 | /* if it's unique, don't ever make it again */ 765 | if (ptr->geno & G_UNIQ) mvitals[mndx].mvflags |= G_EXTINCT; 766 | 767 | /* Once a certain number of monsters are created, don't create any more 768 | * at random (i.e. make them extinct). The previous (3.2) behavior was 769 | * to do this when a certain number had _died_, which didn't make 770 | * much sense. 771 | * This version makes a little more sense but still requires that 772 | * the caller manually decrement mvitals if the monster is created 773 | * under circumstances where one would not logically expect the 774 | * creation to reduce the supply of wild monsters. Monster cloning 775 | * might be one such case, but we go against logic there in order to 776 | * reduce the possibility of abuse. 777 | */ 778 | if (mvitals[mndx].born < 255) mvitals[mndx].born++; 779 | lim = (mndx == PM_NAZGUL ? 9 : mndx == PM_ERINYS ? 3 : MAXMONNO); 780 | if ((int) mvitals[mndx].born >= lim && !(mons[mndx].geno & G_NOGEN) && 781 | !(mvitals[mndx].mvflags & G_EXTINCT)) { 782 | #ifdef DEBUG 783 | pline("Automatically extinguished %s.", 784 | makeplural(mons[mndx].mname)); 785 | #endif 786 | mvitals[mndx].mvflags |= G_EXTINCT; 787 | reset_rndmonst(mndx); 788 | } 789 | 790 | xlth = ptr->pxlth; 791 | if (mmflags & MM_EDOG) xlth += sizeof(struct edog); 792 | else if (mmflags & MM_EMIN) xlth += sizeof(struct emin); 793 | mtmp = newmonst(xlth); 794 | *mtmp = zeromonst; /* clear all entries in structure */ 795 | (void)memset((genericptr_t)mtmp->mextra, 0, xlth); 796 | mtmp->nmon = fmon; 797 | fmon = mtmp; 798 | mtmp->m_id = flags.ident++; 799 | if (!mtmp->m_id) mtmp->m_id = flags.ident++; /* ident overflowed */ 800 | set_mon_data(mtmp, ptr, 0); 801 | mtmp->mxlth = xlth; 802 | mtmp->mnum = mndx; 803 | 804 | mtmp->m_lev = adj_lev(ptr); 805 | if (is_golem(ptr)) { 806 | mtmp->mhpmax = mtmp->mhp = golemhp(mndx); 807 | } else if (is_rider(ptr)) { 808 | /* We want low HP, but a high mlevel so they can attack well */ 809 | mtmp->mhpmax = mtmp->mhp = d(10,8); 810 | } else if (ptr->mlevel > 49) { 811 | /* "special" fixed hp monster 812 | * the hit points are encoded in the mlevel in a somewhat strange 813 | * way to fit in the 50..127 positive range of a signed character 814 | * above the 1..49 that indicate "normal" monster levels */ 815 | mtmp->mhpmax = mtmp->mhp = 2*(ptr->mlevel - 6); 816 | mtmp->m_lev = mtmp->mhp / 4; /* approximation */ 817 | } else if (ptr->mlet == S_DRAGON && mndx >= PM_GRAY_DRAGON) { 818 | /* adult dragons */ 819 | mtmp->mhpmax = mtmp->mhp = (int) (In_endgame(&u.uz) ? 820 | (8 * mtmp->m_lev) : (4 * mtmp->m_lev + d((int)mtmp->m_lev, 4))); 821 | } else if (!mtmp->m_lev) { 822 | mtmp->mhpmax = mtmp->mhp = rnd(4); 823 | } else { 824 | mtmp->mhpmax = mtmp->mhp = d((int)mtmp->m_lev, 8); 825 | if (is_home_elemental(ptr)) 826 | mtmp->mhpmax = (mtmp->mhp *= 3); 827 | } 828 | 829 | if (is_female(ptr)) mtmp->female = TRUE; 830 | else if (is_male(ptr)) mtmp->female = FALSE; 831 | else mtmp->female = rn2(2); /* ignored for neuters */ 832 | 833 | if (In_sokoban(&u.uz) && !mindless(ptr)) /* know about traps here */ 834 | mtmp->mtrapseen = (1L << (PIT - 1)) | (1L << (HOLE - 1)); 835 | 836 | place_monster(mtmp, x, y); 837 | mtmp->mcansee = mtmp->mcanmove = TRUE; 838 | mtmp->mpeaceful = (mmflags & MM_ANGRY) ? FALSE : peace_minded(ptr); 839 | 840 | switch(ptr->mlet) { 841 | case S_MIMIC: 842 | set_mimic_sym(mtmp); 843 | break; 844 | case S_SPIDER: 845 | case S_SNAKE: 846 | if(in_mklev) 847 | if(x && y) 848 | (void) mkobj_at(0, x, y, TRUE); 849 | if(hides_under(ptr) && OBJ_AT(x, y)) 850 | mtmp->mundetected = TRUE; 851 | break; 852 | case S_LIGHT: 853 | case S_ELEMENTAL: 854 | if (mndx == PM_STALKER || mndx == PM_BLACK_LIGHT) { 855 | mtmp->perminvis = TRUE; 856 | mtmp->minvis = TRUE; 857 | } 858 | break; 859 | case S_EEL: 860 | if (is_pool(x, y)) 861 | mtmp->mundetected = TRUE; 862 | break; 863 | case S_LEPRECHAUN: 864 | mtmp->msleeping = 1; 865 | break; 866 | case S_JABBERWOCK: 867 | case S_NYMPH: 868 | if (rn2(5) && !u.uhave.amulet) mtmp->msleeping = 1; 869 | break; 870 | case S_ORC: 871 | if (Race_if(PM_ELF)) mtmp->mpeaceful = FALSE; 872 | break; 873 | case S_UNICORN: 874 | if (is_unicorn(ptr) && 875 | sgn(u.ualign.type) == sgn(ptr->maligntyp)) 876 | mtmp->mpeaceful = TRUE; 877 | break; 878 | case S_BAT: 879 | if (Inhell && is_bat(ptr)) 880 | mon_adjust_speed(mtmp, 2); 881 | break; 882 | } 883 | if ((ct = emits_light(mtmp->data)) > 0) 884 | new_light_source(mtmp->mx, mtmp->my, ct, 885 | LS_MONSTER, (genericptr_t)mtmp); 886 | mitem = 0; /* extra inventory item for this monster */ 887 | 888 | if ((mcham = pm_to_cham(mndx)) != CHAM_ORDINARY) { 889 | /* If you're protected with a ring, don't create 890 | * any shape-changing chameleons -dgk 891 | */ 892 | if (Protection_from_shape_changers) 893 | mtmp->cham = CHAM_ORDINARY; 894 | else { 895 | mtmp->cham = mcham; 896 | (void) newcham(mtmp, rndmonst()); 897 | } 898 | } else if (mndx == PM_WIZARD_OF_YENDOR) { 899 | mtmp->iswiz = TRUE; 900 | flags.no_of_wizards++; 901 | if (flags.no_of_wizards == 1 && Is_earthlevel(&u.uz)) 902 | mitem = SPE_DIG; 903 | } else if (mndx == PM_DJINNI) { 904 | flags.djinni_count++; 905 | } else if (mndx == PM_GHOST) { 906 | flags.ghost_count++; 907 | if (!(mmflags & MM_NONAME)) 908 | mtmp = christen_monst(mtmp, rndghostname()); 909 | } else if (mndx == PM_VLAD_THE_IMPALER) { 910 | mitem = CANDELABRUM_OF_INVOCATION; 911 | } else if (mndx == PM_CROESUS) { 912 | mitem = TWO_HANDED_SWORD; 913 | } else if (ptr->msound == MS_NEMESIS) { 914 | mitem = BELL_OF_OPENING; 915 | } else if (mndx == PM_PESTILENCE) { 916 | mitem = POT_SICKNESS; 917 | } 918 | if (mitem && allow_minvent) (void) mongets(mtmp, mitem); 919 | 920 | if(in_mklev) { 921 | if(((is_ndemon(ptr)) || 922 | (mndx == PM_WUMPUS) || 923 | (mndx == PM_LONG_WORM) || 924 | (mndx == PM_GIANT_EEL)) && !u.uhave.amulet && rn2(5)) 925 | mtmp->msleeping = TRUE; 926 | } else { 927 | if(byyou) { 928 | newsym(mtmp->mx,mtmp->my); 929 | set_apparxy(mtmp); 930 | } 931 | } 932 | if(is_dprince(ptr) && ptr->msound == MS_BRIBE) { 933 | mtmp->mpeaceful = mtmp->minvis = mtmp->perminvis = 1; 934 | if (uwep && uwep->oartifact == ART_EXCALIBUR) 935 | mtmp->mpeaceful = mtmp->mtame = FALSE; 936 | } 937 | #ifndef DCC30_BUG 938 | if (mndx == PM_LONG_WORM && (mtmp->wormno = get_wormno()) != 0) 939 | #else 940 | /* DICE 3.0 doesn't like assigning and comparing mtmp->wormno in the 941 | * same expression. 942 | */ 943 | if (mndx == PM_LONG_WORM && 944 | (mtmp->wormno = get_wormno(), mtmp->wormno != 0)) 945 | #endif 946 | { 947 | /* we can now create worms with tails - 11/91 */ 948 | initworm(mtmp, rn2(5)); 949 | if (count_wsegs(mtmp)) place_worm_tail_randomly(mtmp, x, y); 950 | } 951 | set_malign(mtmp); /* having finished peaceful changes */ 952 | if(anymon) { 953 | if ((ptr->geno & G_SGROUP) && rn2(2)) { 954 | m_initsgrp(mtmp, mtmp->mx, mtmp->my); 955 | } else if (ptr->geno & G_LGROUP) { 956 | if(rn2(3)) m_initlgrp(mtmp, mtmp->mx, mtmp->my); 957 | else m_initsgrp(mtmp, mtmp->mx, mtmp->my); 958 | } 959 | } 960 | 961 | if (allow_minvent) { 962 | if(is_armed(ptr)) 963 | m_initweap(mtmp); /* equip with weapons / armor */ 964 | m_initinv(mtmp); /* add on a few special items incl. more armor */ 965 | m_dowear(mtmp, TRUE); 966 | } else { 967 | /* no initial inventory is allowed */ 968 | if (mtmp->minvent) discard_minvent(mtmp); 969 | mtmp->minvent = (struct obj *)0; /* caller expects this */ 970 | } 971 | if ((ptr->mflags3 & M3_WAITMASK) && !(mmflags & MM_NOWAIT)) { 972 | if (ptr->mflags3 & M3_WAITFORU) 973 | mtmp->mstrategy |= STRAT_WAITFORU; 974 | if (ptr->mflags3 & M3_CLOSE) 975 | mtmp->mstrategy |= STRAT_CLOSE; 976 | } 977 | 978 | if (!in_mklev) 979 | newsym(mtmp->mx,mtmp->my); /* make sure the mon shows up */ 980 | 981 | return(mtmp); 982 | } 983 | 984 | /* used for wand/scroll/spell of create monster */ 985 | /* returns TRUE iff you know monsters have been created */ 986 | boolean 987 | create_critters(cnt, mptr) 988 | int cnt; 989 | struct permonst *mptr; /* usually null; used for confused reading */ 990 | { 991 | coord c; 992 | int x, y; 993 | struct monst *mon; 994 | boolean known = FALSE; 995 | #ifdef WIZARD 996 | boolean ask = wizard; 997 | #endif 998 | 999 | while (cnt--) { 1000 | #ifdef WIZARD 1001 | if (ask) { 1002 | if (create_particular()) { 1003 | known = TRUE; 1004 | continue; 1005 | } 1006 | else ask = FALSE; /* ESC will shut off prompting */ 1007 | } 1008 | #endif 1009 | x = u.ux, y = u.uy; 1010 | /* if in water, try to encourage an aquatic monster 1011 | by finding and then specifying another wet location */ 1012 | if (!mptr && u.uinwater && enexto(&c, x, y, &mons[PM_GIANT_EEL])) 1013 | x = c.x, y = c.y; 1014 | 1015 | mon = makemon(mptr, x, y, NO_MM_FLAGS); 1016 | if (mon && canspotmon(mon)) known = TRUE; 1017 | } 1018 | return known; 1019 | } 1020 | 1021 | #endif /* OVL1 */ 1022 | #ifdef OVL0 1023 | 1024 | STATIC_OVL boolean 1025 | uncommon(mndx) 1026 | int mndx; 1027 | { 1028 | if (mons[mndx].geno & (G_NOGEN | G_UNIQ)) return TRUE; 1029 | if (mvitals[mndx].mvflags & G_GONE) return TRUE; 1030 | if (Inhell) 1031 | return(mons[mndx].maligntyp > A_NEUTRAL); 1032 | else 1033 | return((mons[mndx].geno & G_HELL) != 0); 1034 | } 1035 | 1036 | /* 1037 | * shift the probability of a monster's generation by 1038 | * comparing the dungeon alignment and monster alignment. 1039 | * return an integer in the range of 0-5. 1040 | */ 1041 | STATIC_OVL int 1042 | align_shift(ptr) 1043 | register struct permonst *ptr; 1044 | { 1045 | static NEARDATA long oldmoves = 0L; /* != 1, starting value of moves */ 1046 | static NEARDATA s_level *lev; 1047 | register int alshift; 1048 | 1049 | if(oldmoves != moves) { 1050 | lev = Is_special(&u.uz); 1051 | oldmoves = moves; 1052 | } 1053 | switch((lev) ? lev->flags.align : dungeons[u.uz.dnum].flags.align) { 1054 | default: /* just in case */ 1055 | case AM_NONE: alshift = 0; 1056 | break; 1057 | case AM_LAWFUL: alshift = (ptr->maligntyp+20)/(2*ALIGNWEIGHT); 1058 | break; 1059 | case AM_NEUTRAL: alshift = (20 - abs(ptr->maligntyp))/ALIGNWEIGHT; 1060 | break; 1061 | case AM_CHAOTIC: alshift = (-(ptr->maligntyp-20))/(2*ALIGNWEIGHT); 1062 | break; 1063 | } 1064 | return alshift; 1065 | } 1066 | 1067 | static NEARDATA struct { 1068 | int choice_count; 1069 | char mchoices[SPECIAL_PM]; /* value range is 0..127 */ 1070 | } rndmonst_state = { -1, {0} }; 1071 | 1072 | /* select a random monster type */ 1073 | struct permonst * 1074 | rndmonst() 1075 | { 1076 | register struct permonst *ptr; 1077 | register int mndx, ct; 1078 | 1079 | if (u.uz.dnum == quest_dnum && rn2(7) && (ptr = qt_montype()) != 0) 1080 | return ptr; 1081 | 1082 | if (rndmonst_state.choice_count < 0) { /* need to recalculate */ 1083 | int zlevel, minmlev, maxmlev; 1084 | boolean elemlevel; 1085 | #ifdef REINCARNATION 1086 | boolean upper; 1087 | #endif 1088 | 1089 | rndmonst_state.choice_count = 0; 1090 | /* look for first common monster */ 1091 | for (mndx = LOW_PM; mndx < SPECIAL_PM; mndx++) 1092 | if (!uncommon(mndx)) break; 1093 | if (mndx == SPECIAL_PM) { 1094 | /* evidently they've all been exterminated */ 1095 | #ifdef DEBUG 1096 | pline("rndmonst: no common mons!"); 1097 | #endif 1098 | return (struct permonst *)0; 1099 | } /* else `mndx' now ready for use below */ 1100 | zlevel = level_difficulty(); 1101 | /* determine the level of the weakest monster to make. */ 1102 | minmlev = zlevel / 6; 1103 | /* determine the level of the strongest monster to make. */ 1104 | maxmlev = (zlevel + u.ulevel) / 2; 1105 | #ifdef REINCARNATION 1106 | upper = Is_rogue_level(&u.uz); 1107 | #endif 1108 | elemlevel = In_endgame(&u.uz) && !Is_astralevel(&u.uz); 1109 | 1110 | /* 1111 | * Find out how many monsters exist in the range we have selected. 1112 | */ 1113 | /* (`mndx' initialized above) */ 1114 | for ( ; mndx < SPECIAL_PM; mndx++) { 1115 | ptr = &mons[mndx]; 1116 | rndmonst_state.mchoices[mndx] = 0; 1117 | if (tooweak(mndx, minmlev) || toostrong(mndx, maxmlev)) 1118 | continue; 1119 | #ifdef REINCARNATION 1120 | if (upper && !isupper(def_monsyms[(int)(ptr->mlet)])) continue; 1121 | #endif 1122 | if (elemlevel && wrong_elem_type(ptr)) continue; 1123 | if (uncommon(mndx)) continue; 1124 | if (Inhell && (ptr->geno & G_NOHELL)) continue; 1125 | ct = (int)(ptr->geno & G_FREQ) + align_shift(ptr); 1126 | if (ct < 0 || ct > 127) 1127 | panic("rndmonst: bad count [#%d: %d]", mndx, ct); 1128 | rndmonst_state.choice_count += ct; 1129 | rndmonst_state.mchoices[mndx] = (char)ct; 1130 | } 1131 | /* 1132 | * Possible modification: if choice_count is "too low", 1133 | * expand minmlev..maxmlev range and try again. 1134 | */ 1135 | } /* choice_count+mchoices[] recalc */ 1136 | 1137 | if (rndmonst_state.choice_count <= 0) { 1138 | /* maybe no common mons left, or all are too weak or too strong */ 1139 | #ifdef DEBUG 1140 | Norep("rndmonst: choice_count=%d", rndmonst_state.choice_count); 1141 | #endif 1142 | return (struct permonst *)0; 1143 | } 1144 | 1145 | /* 1146 | * Now, select a monster at random. 1147 | */ 1148 | ct = rnd(rndmonst_state.choice_count); 1149 | for (mndx = LOW_PM; mndx < SPECIAL_PM; mndx++) 1150 | if ((ct -= (int)rndmonst_state.mchoices[mndx]) <= 0) break; 1151 | 1152 | if (mndx == SPECIAL_PM || uncommon(mndx)) { /* shouldn't happen */ 1153 | impossible("rndmonst: bad `mndx' [#%d]", mndx); 1154 | return (struct permonst *)0; 1155 | } 1156 | return &mons[mndx]; 1157 | } 1158 | 1159 | /* called when you change level (experience or dungeon depth) or when 1160 | monster species can no longer be created (genocide or extinction) */ 1161 | void 1162 | reset_rndmonst(mndx) 1163 | int mndx; /* particular species that can no longer be created */ 1164 | { 1165 | /* cached selection info is out of date */ 1166 | if (mndx == NON_PM) { 1167 | rndmonst_state.choice_count = -1; /* full recalc needed */ 1168 | } else if (mndx < SPECIAL_PM) { 1169 | rndmonst_state.choice_count -= rndmonst_state.mchoices[mndx]; 1170 | rndmonst_state.mchoices[mndx] = 0; 1171 | } /* note: safe to ignore extinction of unique monsters */ 1172 | } 1173 | 1174 | #endif /* OVL0 */ 1175 | #ifdef OVL1 1176 | 1177 | /* The routine below is used to make one of the multiple types 1178 | * of a given monster class. The second parameter specifies a 1179 | * special casing bit mask to allow the normal genesis 1180 | * masks to be deactivated. Returns 0 if no monsters 1181 | * in that class can be made. 1182 | */ 1183 | 1184 | struct permonst * 1185 | mkclass(class,spc) 1186 | char class; 1187 | int spc; 1188 | { 1189 | register int first, last, num = 0; 1190 | int maxmlev, mask = (G_NOGEN | G_UNIQ) & ~spc; 1191 | 1192 | maxmlev = level_difficulty() >> 1; 1193 | if(class < 1 || class >= MAXMCLASSES) { 1194 | impossible("mkclass called with bad class!"); 1195 | return((struct permonst *) 0); 1196 | } 1197 | /* Assumption #1: monsters of a given class are contiguous in the 1198 | * mons[] array. 1199 | */ 1200 | for (first = LOW_PM; first < SPECIAL_PM; first++) 1201 | if (mons[first].mlet == class) break; 1202 | if (first == SPECIAL_PM) return (struct permonst *) 0; 1203 | 1204 | for (last = first; 1205 | last < SPECIAL_PM && mons[last].mlet == class; last++) 1206 | if (!(mvitals[last].mvflags & G_GONE) && !(mons[last].geno & mask) 1207 | && !is_placeholder(&mons[last])) { 1208 | /* consider it */ 1209 | if(num && toostrong(last, maxmlev) && 1210 | monstr[last] != monstr[last-1] && rn2(2)) break; 1211 | num += mons[last].geno & G_FREQ; 1212 | } 1213 | 1214 | if(!num) return((struct permonst *) 0); 1215 | 1216 | /* Assumption #2: monsters of a given class are presented in ascending 1217 | * order of strength. 1218 | */ 1219 | for(num = rnd(num); num > 0; first++) 1220 | if (!(mvitals[first].mvflags & G_GONE) && !(mons[first].geno & mask) 1221 | && !is_placeholder(&mons[first])) { 1222 | /* skew towards lower value monsters at lower exp. levels */ 1223 | num -= mons[first].geno & G_FREQ; 1224 | if (num && adj_lev(&mons[first]) > (u.ulevel*2)) { 1225 | /* but not when multiple monsters are same level */ 1226 | if (mons[first].mlevel != mons[first+1].mlevel) 1227 | num--; 1228 | } 1229 | } 1230 | first--; /* correct an off-by-one error */ 1231 | 1232 | return(&mons[first]); 1233 | } 1234 | 1235 | int 1236 | adj_lev(ptr) /* adjust strength of monsters based on u.uz and u.ulevel */ 1237 | register struct permonst *ptr; 1238 | { 1239 | int tmp, tmp2; 1240 | 1241 | if (ptr == &mons[PM_WIZARD_OF_YENDOR]) { 1242 | /* does not depend on other strengths, but does get stronger 1243 | * every time he is killed 1244 | */ 1245 | tmp = ptr->mlevel + mvitals[PM_WIZARD_OF_YENDOR].died; 1246 | if (tmp > 49) tmp = 49; 1247 | return tmp; 1248 | } 1249 | 1250 | if((tmp = ptr->mlevel) > 49) return(50); /* "special" demons/devils */ 1251 | tmp2 = (level_difficulty() - tmp); 1252 | if(tmp2 < 0) tmp--; /* if mlevel > u.uz decrement tmp */ 1253 | else tmp += (tmp2 / 5); /* else increment 1 per five diff */ 1254 | 1255 | tmp2 = (u.ulevel - ptr->mlevel); /* adjust vs. the player */ 1256 | if(tmp2 > 0) tmp += (tmp2 / 4); /* level as well */ 1257 | 1258 | tmp2 = (3 * ((int) ptr->mlevel))/ 2; /* crude upper limit */ 1259 | if (tmp2 > 49) tmp2 = 49; /* hard upper limit */ 1260 | return((tmp > tmp2) ? tmp2 : (tmp > 0 ? tmp : 0)); /* 0 lower limit */ 1261 | } 1262 | 1263 | #endif /* OVL1 */ 1264 | #ifdef OVLB 1265 | 1266 | struct permonst * 1267 | grow_up(mtmp, victim) /* `mtmp' might "grow up" into a bigger version */ 1268 | struct monst *mtmp, *victim; 1269 | { 1270 | int oldtype, newtype, max_increase, cur_increase, 1271 | lev_limit, hp_threshold; 1272 | struct permonst *ptr = mtmp->data; 1273 | 1274 | /* monster died after killing enemy but before calling this function */ 1275 | /* currently possible if killing a gas spore */ 1276 | if (mtmp->mhp <= 0) 1277 | return ((struct permonst *)0); 1278 | 1279 | /* growth limits differ depending on method of advancement */ 1280 | if (victim) { /* killed a monster */ 1281 | /* 1282 | * The HP threshold is the maximum number of hit points for the 1283 | * current level; once exceeded, a level will be gained. 1284 | * Possible bug: if somehow the hit points are already higher 1285 | * than that, monster will gain a level without any increase in HP. 1286 | */ 1287 | hp_threshold = mtmp->m_lev * 8; /* normal limit */ 1288 | if (!mtmp->m_lev) 1289 | hp_threshold = 4; 1290 | else if (is_golem(ptr)) /* strange creatures */ 1291 | hp_threshold = ((mtmp->mhpmax / 10) + 1) * 10 - 1; 1292 | else if (is_home_elemental(ptr)) 1293 | hp_threshold *= 3; 1294 | lev_limit = 3 * (int)ptr->mlevel / 2; /* same as adj_lev() */ 1295 | /* number of hit points to gain; unlike for the player, we put 1296 | the limit at the bottom of the next level rather than the top */ 1297 | max_increase = rnd((int)victim->m_lev + 1); 1298 | if (mtmp->mhpmax + max_increase > hp_threshold + 1) 1299 | max_increase = max((hp_threshold + 1) - mtmp->mhpmax, 0); 1300 | cur_increase = (max_increase > 1) ? rn2(max_increase) : 0; 1301 | } else { 1302 | /* a gain level potion or wraith corpse; always go up a level 1303 | unless already at maximum (49 is hard upper limit except 1304 | for demon lords, who start at 50 and can't go any higher) */ 1305 | max_increase = cur_increase = rnd(8); 1306 | hp_threshold = 0; /* smaller than `mhpmax + max_increase' */ 1307 | lev_limit = 50; /* recalc below */ 1308 | } 1309 | 1310 | mtmp->mhpmax += max_increase; 1311 | mtmp->mhp += cur_increase; 1312 | if (mtmp->mhpmax <= hp_threshold) 1313 | return ptr; /* doesn't gain a level */ 1314 | 1315 | if (is_mplayer(ptr)) lev_limit = 30; /* same as player */ 1316 | else if (lev_limit < 5) lev_limit = 5; /* arbitrary */ 1317 | else if (lev_limit > 49) lev_limit = (ptr->mlevel > 49 ? 50 : 49); 1318 | 1319 | /* note: none of the monsters with special hit point calculations 1320 | have both little and big forms */ 1321 | oldtype = monsndx(ptr); 1322 | newtype = little_to_big(oldtype); 1323 | if (newtype == PM_PRIEST && mtmp->female) newtype = PM_PRIESTESS; 1324 | if ((int)++mtmp->m_lev >= mons[newtype].mlevel && newtype != oldtype) { 1325 | ptr = &mons[newtype]; 1326 | if (mvitals[newtype].mvflags & G_GENOD) { /* allow G_EXTINCT */ 1327 | if (sensemon(mtmp)) 1328 | pline("As %s grows up into %s, %s %s!", mon_nam(mtmp), 1329 | an(ptr->mname), he[pronoun_gender(mtmp)], 1330 | nonliving(ptr) ? "expires" : "dies"); 1331 | set_mon_data(mtmp, ptr, -1); /* keep mvitals[] accurate */ 1332 | mondied(mtmp); 1333 | return (struct permonst *)0; 1334 | } 1335 | set_mon_data(mtmp, ptr, 1); /* preserve intrinsics */ 1336 | newsym(mtmp->mx, mtmp->my); /* color may change */ 1337 | lev_limit = (int)mtmp->m_lev; /* never undo increment */ 1338 | } 1339 | /* sanity checks */ 1340 | if ((int)mtmp->m_lev > lev_limit) { 1341 | mtmp->m_lev--; /* undo increment */ 1342 | /* HP might have been allowed to grow when it shouldn't */ 1343 | if (mtmp->mhpmax == hp_threshold + 1) mtmp->mhpmax--; 1344 | } 1345 | if (mtmp->mhpmax > 50*8) mtmp->mhpmax = 50*8; /* absolute limit */ 1346 | if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; 1347 | 1348 | return ptr; 1349 | } 1350 | 1351 | #endif /* OVLB */ 1352 | #ifdef OVL1 1353 | 1354 | int 1355 | mongets(mtmp, otyp) 1356 | register struct monst *mtmp; 1357 | register int otyp; 1358 | { 1359 | register struct obj *otmp; 1360 | int spe; 1361 | 1362 | if (!otyp) return 0; 1363 | otmp = mksobj(otyp, TRUE, FALSE); 1364 | if (otmp) { 1365 | if (mtmp->data->mlet == S_DEMON) { 1366 | /* demons never get blessed objects */ 1367 | if (otmp->blessed) curse(otmp); 1368 | } else if(is_lminion(mtmp->data)) { 1369 | /* lawful minions don't get cursed, bad, or rusting objects */ 1370 | otmp->cursed = FALSE; 1371 | if(otmp->spe < 0) otmp->spe = 0; 1372 | otmp->oerodeproof = TRUE; 1373 | } else if(is_mplayer(mtmp->data) && is_sword(otmp)) { 1374 | otmp->spe = (3 + rn2(4)); 1375 | } 1376 | 1377 | if(otmp->otyp == CANDELABRUM_OF_INVOCATION) { 1378 | otmp->spe = 0; 1379 | otmp->age = 0L; 1380 | otmp->lamplit = FALSE; 1381 | otmp->blessed = otmp->cursed = FALSE; 1382 | } else if (otmp->otyp == BELL_OF_OPENING) { 1383 | otmp->blessed = otmp->cursed = FALSE; 1384 | } else if (otmp->otyp == SPE_BOOK_OF_THE_DEAD) { 1385 | otmp->blessed = FALSE; 1386 | otmp->cursed = TRUE; 1387 | } 1388 | 1389 | /* leaders don't tolerate inferior quality battle gear */ 1390 | if (is_prince(mtmp->data)) { 1391 | if (otmp->oclass == WEAPON_CLASS && otmp->spe < 1) 1392 | otmp->spe = 1; 1393 | else if (otmp->oclass == ARMOR_CLASS && otmp->spe < 0) 1394 | otmp->spe = 0; 1395 | } 1396 | 1397 | spe = otmp->spe; 1398 | (void) mpickobj(mtmp, otmp); /* might free otmp */ 1399 | return(spe); 1400 | } else return(0); 1401 | } 1402 | 1403 | #endif /* OVL1 */ 1404 | #ifdef OVLB 1405 | 1406 | int 1407 | golemhp(type) 1408 | int type; 1409 | { 1410 | switch(type) { 1411 | case PM_STRAW_GOLEM: return 20; 1412 | case PM_PAPER_GOLEM: return 20; 1413 | case PM_ROPE_GOLEM: return 30; 1414 | case PM_LEATHER_GOLEM: return 40; 1415 | case PM_GOLD_GOLEM: return 40; 1416 | case PM_WOOD_GOLEM: return 50; 1417 | case PM_FLESH_GOLEM: return 40; 1418 | case PM_CLAY_GOLEM: return 50; 1419 | case PM_STONE_GOLEM: return 60; 1420 | case PM_GLASS_GOLEM: return 60; 1421 | case PM_IRON_GOLEM: return 80; 1422 | default: return 0; 1423 | } 1424 | } 1425 | 1426 | #endif /* OVLB */ 1427 | #ifdef OVL1 1428 | 1429 | /* 1430 | * Alignment vs. yours determines monster's attitude to you. 1431 | * ( some "animal" types are co-aligned, but also hungry ) 1432 | */ 1433 | boolean 1434 | peace_minded(ptr) 1435 | register struct permonst *ptr; 1436 | { 1437 | aligntyp mal = ptr->maligntyp, ual = u.ualign.type; 1438 | 1439 | if (always_peaceful(ptr)) return TRUE; 1440 | if (always_hostile(ptr)) return FALSE; 1441 | if (ptr->msound == MS_LEADER || ptr->msound == MS_GUARDIAN) 1442 | return TRUE; 1443 | if (ptr->msound == MS_NEMESIS) return FALSE; 1444 | 1445 | if (race_peaceful(ptr)) return TRUE; 1446 | if (race_hostile(ptr)) return FALSE; 1447 | 1448 | /* the monster is hostile if its alignment is different from the 1449 | * player's */ 1450 | if (sgn(mal) != sgn(ual)) return FALSE; 1451 | 1452 | /* Negative monster hostile to player with Amulet. */ 1453 | if (mal < A_NEUTRAL && u.uhave.amulet) return FALSE; 1454 | 1455 | /* minions are hostile to players that have strayed at all */ 1456 | if (is_minion(ptr)) return((boolean)(u.ualign.record >= 0)); 1457 | 1458 | /* Last case: a chance of a co-aligned monster being 1459 | * hostile. This chance is greater if the player has strayed 1460 | * (u.ualign.record negative) or the monster is not strongly aligned. 1461 | */ 1462 | return((boolean)(!!rn2(16 + (u.ualign.record < -15 ? -15 : u.ualign.record)) && 1463 | !!rn2(2 + abs(mal)))); 1464 | } 1465 | 1466 | /* Set malign to have the proper effect on player alignment if monster is 1467 | * killed. Negative numbers mean it's bad to kill this monster; positive 1468 | * numbers mean it's good. Since there are more hostile monsters than 1469 | * peaceful monsters, the penalty for killing a peaceful monster should be 1470 | * greater than the bonus for killing a hostile monster to maintain balance. 1471 | * Rules: 1472 | * it's bad to kill peaceful monsters, potentially worse to kill always- 1473 | * peaceful monsters 1474 | * it's never bad to kill a hostile monster, although it may not be good 1475 | */ 1476 | void 1477 | set_malign(mtmp) 1478 | struct monst *mtmp; 1479 | { 1480 | schar mal = mtmp->data->maligntyp; 1481 | boolean coaligned; 1482 | 1483 | if (mtmp->ispriest || mtmp->isminion) { 1484 | /* some monsters have individual alignments; check them */ 1485 | if (mtmp->ispriest) 1486 | mal = EPRI(mtmp)->shralign; 1487 | else if (mtmp->isminion) 1488 | mal = EMIN(mtmp)->min_align; 1489 | /* unless alignment is none, set mal to -5,0,5 */ 1490 | /* (see align.h for valid aligntyp values) */ 1491 | if(mal != A_NONE) 1492 | mal *= 5; 1493 | } 1494 | 1495 | coaligned = (sgn(mal) == sgn(u.ualign.type)); 1496 | if (mtmp->data->msound == MS_LEADER) { 1497 | mtmp->malign = -20; 1498 | } else if (mal == A_NONE) { 1499 | if (mtmp->mpeaceful) 1500 | mtmp->malign = 0; 1501 | else 1502 | mtmp->malign = 20; /* really hostile */ 1503 | } else if (always_peaceful(mtmp->data)) { 1504 | int absmal = abs(mal); 1505 | if (mtmp->mpeaceful) 1506 | mtmp->malign = -3*max(5,absmal); 1507 | else 1508 | mtmp->malign = 3*max(5,absmal); /* renegade */ 1509 | } else if (always_hostile(mtmp->data)) { 1510 | int absmal = abs(mal); 1511 | if (coaligned) 1512 | mtmp->malign = 0; 1513 | else 1514 | mtmp->malign = max(5,absmal); 1515 | } else if (coaligned) { 1516 | int absmal = abs(mal); 1517 | if (mtmp->mpeaceful) 1518 | mtmp->malign = -3*max(3,absmal); 1519 | else /* renegade */ 1520 | mtmp->malign = max(3,absmal); 1521 | } else /* not coaligned and therefore hostile */ 1522 | mtmp->malign = abs(mal); 1523 | } 1524 | 1525 | #endif /* OVL1 */ 1526 | #ifdef OVLB 1527 | 1528 | static NEARDATA char syms[] = { 1529 | MAXOCLASSES, MAXOCLASSES+1, RING_CLASS, WAND_CLASS, WEAPON_CLASS, 1530 | FOOD_CLASS, GOLD_CLASS, SCROLL_CLASS, POTION_CLASS, ARMOR_CLASS, 1531 | AMULET_CLASS, TOOL_CLASS, ROCK_CLASS, GEM_CLASS, SPBOOK_CLASS, 1532 | S_MIMIC_DEF, S_MIMIC_DEF, S_MIMIC_DEF, 1533 | }; 1534 | 1535 | void 1536 | set_mimic_sym(mtmp) /* KAA, modified by ERS */ 1537 | register struct monst *mtmp; 1538 | { 1539 | int typ, roomno, rt; 1540 | unsigned appear, ap_type; 1541 | int s_sym; 1542 | struct obj *otmp; 1543 | int mx, my; 1544 | 1545 | if (!mtmp) return; 1546 | mx = mtmp->mx; my = mtmp->my; 1547 | typ = levl[mx][my].typ; 1548 | /* only valid for INSIDE of room */ 1549 | roomno = levl[mx][my].roomno - ROOMOFFSET; 1550 | if (roomno >= 0) 1551 | rt = rooms[roomno].rtype; 1552 | #ifdef SPECIALIZATION 1553 | else if (IS_ROOM(typ)) 1554 | rt = OROOM, roomno = 0; 1555 | #endif 1556 | else rt = 0; /* roomno < 0 case for GCC_WARN */ 1557 | 1558 | if (OBJ_AT(mx, my)) { 1559 | ap_type = M_AP_OBJECT; 1560 | appear = level.objects[mx][my]->otyp; 1561 | } else if (IS_DOOR(typ) || IS_WALL(typ) || 1562 | typ == SDOOR || typ == SCORR) { 1563 | ap_type = M_AP_FURNITURE; 1564 | /* 1565 | * If there is a wall to the left that connects to this 1566 | * location, then the mimic mimics a horizontal closed door. 1567 | * This does not allow doors to be in corners of rooms. 1568 | */ 1569 | if (mx != 0 && 1570 | (levl[mx-1][my].typ == HWALL || 1571 | levl[mx-1][my].typ == TLCORNER || 1572 | levl[mx-1][my].typ == TRWALL || 1573 | levl[mx-1][my].typ == BLCORNER || 1574 | levl[mx-1][my].typ == TDWALL || 1575 | levl[mx-1][my].typ == CROSSWALL|| 1576 | levl[mx-1][my].typ == TUWALL )) 1577 | appear = S_hcdoor; 1578 | else 1579 | appear = S_vcdoor; 1580 | 1581 | if(!mtmp->minvis || See_invisible) 1582 | block_point(mx,my); /* vision */ 1583 | } else if (level.flags.is_maze_lev && rn2(2)) { 1584 | ap_type = M_AP_OBJECT; 1585 | appear = STATUE; 1586 | } else if (roomno < 0) { 1587 | ap_type = M_AP_OBJECT; 1588 | appear = BOULDER; 1589 | if(!mtmp->minvis || See_invisible) 1590 | block_point(mx,my); /* vision */ 1591 | } else if (rt == ZOO || rt == VAULT) { 1592 | ap_type = M_AP_OBJECT; 1593 | appear = GOLD_PIECE; 1594 | } else if (rt == DELPHI) { 1595 | if (rn2(2)) { 1596 | ap_type = M_AP_OBJECT; 1597 | appear = STATUE; 1598 | } else { 1599 | ap_type = M_AP_FURNITURE; 1600 | appear = S_fountain; 1601 | } 1602 | } else if (rt == TEMPLE) { 1603 | ap_type = M_AP_FURNITURE; 1604 | appear = S_altar; 1605 | /* 1606 | * We won't bother with beehives, morgues, barracks, throne rooms 1607 | * since they shouldn't contain too many mimics anyway... 1608 | */ 1609 | } else if (rt >= SHOPBASE) { 1610 | s_sym = get_shop_item(rt - SHOPBASE); 1611 | if (s_sym < 0) { 1612 | ap_type = M_AP_OBJECT; 1613 | appear = -s_sym; 1614 | } else { 1615 | if (s_sym == RANDOM_CLASS) 1616 | s_sym = syms[rn2((int)sizeof(syms)-2) + 2]; 1617 | goto assign_sym; 1618 | } 1619 | } else { 1620 | s_sym = syms[rn2((int)sizeof(syms))]; 1621 | assign_sym: 1622 | if (s_sym >= MAXOCLASSES) { 1623 | ap_type = M_AP_FURNITURE; 1624 | appear = s_sym == MAXOCLASSES ? S_upstair : S_dnstair; 1625 | } else if (s_sym == GOLD_CLASS) { 1626 | ap_type = M_AP_OBJECT; 1627 | appear = GOLD_PIECE; 1628 | } else { 1629 | ap_type = M_AP_OBJECT; 1630 | if (s_sym == S_MIMIC_DEF) { 1631 | appear = STRANGE_OBJECT; 1632 | } else { 1633 | otmp = mkobj( (char) s_sym, FALSE ); 1634 | appear = otmp->otyp; 1635 | /* make sure container contents are free'ed */ 1636 | obfree(otmp, (struct obj *) 0); 1637 | } 1638 | } 1639 | } 1640 | mtmp->m_ap_type = ap_type; 1641 | mtmp->mappearance = appear; 1642 | } 1643 | 1644 | #endif /* OVLB */ 1645 | 1646 | /*makemon.c*/