Source:NetHack 3.0.0/mkobj.c

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

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

1.   /*	SCCS Id: @(#)mkobj.c	3.0	88/10/30 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.   struct icp { 8.       int  iprob; /* probability of an item type */ 9.       char ilet;	/* item class */ 10.  };  11.    12.   const struct icp mkobjprobs[] = { 13.  {10, WEAPON_SYM}, 14.  {10, ARMOR_SYM}, 15.  {20, FOOD_SYM}, 16.  { 8, TOOL_SYM}, 17.  { 8, GEM_SYM}, 18.  #ifdef SPELLS 19.  {16, POTION_SYM}, 20.  {16, SCROLL_SYM}, 21.  { 4, SPBOOK_SYM}, 22.  #else 23.  {18, POTION_SYM}, 24.  {18, SCROLL_SYM}, 25.  #endif 26.  { 4, WAND_SYM}, 27.  { 3, RING_SYM}, 28.  { 1, AMULET_SYM}}; 29.   30.   const struct icp boxiprobs[] = { 31.  {18, GEM_SYM}, 32.  #ifdef SPELLS 33.  {15, FOOD_SYM}, 34.  {20, POTION_SYM}, 35.  {20, SCROLL_SYM}, 36.  {15, SPBOOK_SYM}, 37.  #else 38.  {20, FOOD_SYM}, 39.  {25, POTION_SYM}, 40.  {25, SCROLL_SYM}, 41.  #endif 42.  { 6, WAND_SYM}, 43.  { 5, RING_SYM}, 44.  { 1, AMULET_SYM}}; 45.   46.   #ifdef REINCARNATION 47.  const struct icp rogueprobs[] = { 48.  {12, WEAPON_SYM}, 49.  {12, ARMOR_SYM}, 50.  {22, FOOD_SYM}, 51.  {22, POTION_SYM}, 52.  {22, SCROLL_SYM}, 53.  { 5, WAND_SYM}, 54.  { 5, RING_SYM}}; 55.  #endif 56.   57.   const struct icp hellprobs[] = { 58.  {20, WEAPON_SYM}, 59.  {20, ARMOR_SYM}, 60.  {16, FOOD_SYM}, 61.  {12, TOOL_SYM}, 62.  {10, GEM_SYM}, 63.  { 1, POTION_SYM}, 64.  { 1, SCROLL_SYM}, 65.  { 8, WAND_SYM}, 66.  { 8, RING_SYM}, 67.  { 4, AMULET_SYM}}; 68.   69.   static int mksx=0, mksy=0; 70.   71.   struct obj * 72.  mkobj_at(let,x,y) 73.  char let; 74.  int x,y; 75.  {  76.   	register struct obj *otmp; 77.   78.   	mksx = x; mksy = y;  79. /* We might need to know the X, Y coordinates while creating the 80.  	 * object, i.e. to insure shop boxes are empty. 81.  	 * Yes, this is a horrible kludge...  82. */ 83.   	otmp = mkobj(let,TRUE); 84.  	otmp->ox = x;  85. otmp->oy = y; 86. otmp->nobj = fobj; 87.  	fobj = otmp; 88.  	levl[x][y].omask = 1; 89.  	mksx = mksy = 0; 90.  	return(otmp); 91.  }  92.    93.   struct obj * 94.  mksobj_at(otyp,x,y) 95.  int otyp,x,y; 96.  {  97.   	register struct obj *otmp; 98.   99.   	mksx = x; mksy = y;  100. otmp = mksobj(otyp,TRUE); 101. 	otmp->ox = x;  102. otmp->oy = y; 103. otmp->nobj = fobj; 104. 	levl[x][y].omask = 1; 105. 	mksx = mksy = 0; 106. 	return((fobj = otmp)); 107. }  108.   109.  struct obj * 110. mkobj(let, artif) 111. char let; 112. boolean artif; 113. {  114.  	register int tprob, i, prob = rnd(1000); 115.  116.  	if(let == RANDOM_SYM) { 117. 		struct icp *iprobs = 118. #ifdef REINCARNATION 119. 				    (dlevel == rogue_level) ? rogueprobs : 120. #endif 121. 				    Inhell ? hellprobs : 122. 				    mkobjprobs; 123.  124.  		for(tprob = rnd(100);  125.  		    (tprob -= iprobs->iprob) > 0;  126.  		    iprobs++); 127. 		let = iprobs->ilet; 128. 	}  129.   130.  	i = bases[letindex(let)]; 131. 	while((prob -= objects[i].oc_prob) > 0) i++; 132.  133.  	if(objects[i].oc_olet != let || !objects[i].oc_name) 134. 		panic("probtype error, let=%c i=%d", let, i); 135.  136.  	return(mksobj(i, artif)); 137. }  138.   139.  static void 140. mkbox_cnts(box) 141. /* Note: does not check to see if it overloaded the box weight; usually 142.  * possible only with corpses in ice boxes. 143.  */  144.  struct obj *box; 145. {  146.  	register int n;  147. register struct obj *otmp; 148.  149.  	if(in_shop(mksx, mksy)) return; /* boxes are empty in shops */ 150.  151.  	switch(box->otyp) { 152. 		case ICE_BOX: 		n = 20; break; 153. 		case CHEST:		n = 5; break; 154. 		case LARGE_BOX:		n = 3; break; 155. 		case SACK: 156. 		case BAG_OF_HOLDING:	n = 1; break; 157. 		default:		n = 0; break; 158. 	}  159.   160.  	for(n = rn2(n+1); n > 0; n--) { 161. 	    if (box->otyp == ICE_BOX) { 162. 		otmp = mksobj(CORPSE, TRUE); 163. 		otmp->age = moves; 164. 	    } else { 165. 		register int tprob; 166. 		struct icp *iprobs = boxiprobs; 167.  168.  		for(tprob = rnd(100);  169.  		    (tprob -= iprobs->iprob) > 0;  170.  		    iprobs++); 171. 		otmp = mkobj(iprobs->ilet, TRUE); 172. 	    }  173.  	    if (otmp) { 174. 		otmp->cobj = box; 175. 		otmp->nobj = fcobj; 176. 		fcobj = otmp; 177. 		inc_cwt(box, otmp); 178. 	    }  179.  	}  180.  	return; 181. }  182.   183.  int 184. rndmonnum {	/* select a random, common monster type */ 185.  186.  	register struct permonst *ptr; 187. 	register int	i; 188.  189.  	/* Plan A: get a level-appropriate common monster */ 190. 	ptr = rndmonst; 191. 	if (ptr) return(monsndx(ptr)); 192.  193.  	/* Plan B: get any common monster */ 194. 	do { 195. 	    ptr = &mons[(i = rn2(NUMMONS))]; 196. 	} while((ptr->geno & G_NOGEN) || (!Inhell && (ptr->geno & G_HELL))); 197.  198.  	return(i); 199. }  200.   201.  const char dknowns[] = { WAND_SYM, RING_SYM, POTION_SYM, SCROLL_SYM, GEM_SYM, 202. #ifdef SPELLS 203. SPBOOK_SYM, 204. #endif 205. WEAPON_SYM, 0}; 206.  207.  /*ARGSUSED*/ 208. struct obj * 209. mksobj(otyp, artif) 210. int otyp; 211. boolean artif; 212. {  213.  	int tryct; 214. 	struct obj *otmp; 215. 	char let = objects[otyp].oc_olet; 216.  217.  	otmp = newobj(0); 218. 	*otmp = zeroobj; 219. 	otmp->age = moves; 220. 	otmp->o_id = flags.ident++; 221. 	otmp->quan = 1; 222. 	otmp->olet = let; 223. 	otmp->otyp = otyp; 224. 	otmp->dknown = index(dknowns, let) ? 0 : 1; 225.  	if (!uses_known(otmp)) 226. 		otmp->known = 1; 227. 	switch(let) { 228. 	case WEAPON_SYM: 229. 		otmp->quan = (otmp->otyp <= SHURIKEN) ? rn1(6,6) : 1; 230. 		if(!rn2(11)) { 231. 			otmp->spe = rne(2); 232. 			otmp->blessed = rn2(2); 233. 		} else if(!rn2(10)) { 234. 			curse(otmp); 235. 			otmp->spe = -rne(2); 236. 		} else	blessorcurse(otmp, 10); 237.  238.  #ifdef NAMED_ITEMS 239. 		if(artif && !rn2(20)) mkartifact(&otmp); 240. #endif 241. 		break; 242. 	case FOOD_SYM: 243. 		if(otmp->otyp == CORPSE) { 244. 		    /* overridden by mkcorpse_at */ 245. 		    do otmp->corpsenm = rndmonnum; 246. 		    while (mons[otmp->corpsenm].geno & G_NOCORPSE); 247. 		    break; 248. 		} else if(otmp->otyp == EGG) { 249. 		    if(!rn2(3)) {		/* "live" eggs */ 250. 			register struct permonst *ptr; 251. 			for(tryct = 0;  252.  			    (!(ptr = rndmonst) || 253. 			    (!lays_eggs(ptr) && ptr != &mons[PM_KILLER_BEE])) &&  254.  				tryct < 100;  255.  			    tryct++); 256. 			if(tryct < 100)	otmp->corpsenm = monsndx(ptr); 257. 			else		otmp->corpsenm = -1; /* empty */ 258. 		    } else		otmp->corpsenm = -1; /* empty */ 259. 		} else if(otmp->otyp == TIN) { 260. 		    if(!rn2(10)) { 261. 			otmp->spe = 1;		/* spinach */ 262. 			otmp->corpsenm = -1; 263. 		    } else do { 264. 			otmp->corpsenm = rndmonnum; 265. 		    } while (mons[otmp->corpsenm].geno & G_NOCORPSE); 266. 		    blessorcurse(otmp, 10); 267. 		} else if (otmp->otyp == SLIME_MOLD) 268. 		    otmp->spe = current_fruit; 269. 		/* fall into next case */ 270. 	case GEM_SYM: 271. 		if (otmp->otyp == LOADSTONE) curse(otmp); 272. 		else if (otmp->otyp == ROCK) otmp->quan = rn1(6,6); 273. 		else if (otmp->otyp != LUCKSTONE && !rn2(6)) otmp->quan = 2; 274. 		else otmp->quan = 1; 275. 		break; 276. 	case TOOL_SYM: 277. 	    switch(otmp->otyp) { 278. 		case LAMP:		otmp->spe = rnd(10); 279. 					blessorcurse(otmp, 5); 280. 					break; 281. 		case MAGIC_LAMP:	otmp->spe = 1; 282. 					blessorcurse(otmp, 2); 283. 					break; 284. 		case KEY:		/* key # index */ 285. 		case SKELETON_KEY:	otmp->spe = rn2(N_LOX); 286. 					break; 287. 		case CHEST:		/* lock # index */ 288. 		case LARGE_BOX:		otmp->spe = rn2(N_LOX); 289. 					otmp->olocked = !!(rn2(5)); 290. 					otmp->otrapped = !(rn2(10)); 291. 		case ICE_BOX: 292. 		case SACK: 293. 		case BAG_OF_HOLDING:	mkbox_cnts(otmp); 294. 					break; 295. 		case MAGIC_MARKER:	otmp->spe = rn1(70,30); 296. 					break; 297. 		case CRYSTAL_BALL:	otmp->spe = rnd(5); 298. 					blessorcurse(otmp, 2); 299. 					break; 300. 		case BAG_OF_TRICKS:	otmp->spe = rnd(20); 301. 					break; 302. 		case FIGURINE:		otmp->corpsenm = rndmonnum; 303. 					blessorcurse(otmp, 4); 304. 					break; 305. #ifdef MUSIC 306. 		case MAGIC_FLUTE: 307. 		case MAGIC_HARP: 308. 		case FROST_HORN: 309. 		case FIRE_HORN: 310. 		case DRUM_OF_EARTHQUAKE: 311. 					otmp->spe = rn1(5,4); 312. 					break; 313. #endif /* MUSIC /**/ 314. 	    }  315.  	    break; 316. 	case AMULET_SYM: 317. 		if(rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION || 318. 		   otmp->otyp == AMULET_OF_CHANGE || 319. 		   otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) { 320. 			curse(otmp); 321. 		} else	blessorcurse(otmp, 10); 322. 	case VENOM_SYM: 323. 	case CHAIN_SYM: 324. 	case BALL_SYM: 325. 		break; 326. 	case POTION_SYM: 327. 	case SCROLL_SYM: 328. #ifdef MAIL 329. 		if (otmp->otyp != SCR_MAIL) 330. #endif 331. 			blessorcurse(otmp, 4); 332. 		break; 333. #ifdef SPELLS 334. 	case SPBOOK_SYM: 335. 		blessorcurse(otmp, 17); 336. 		break; 337. #endif 338. 	case ARMOR_SYM: 339. 		if(rn2(10) && (otmp->otyp == FUMBLE_BOOTS || 340. 		   otmp->otyp == LEVITATION_BOOTS || 341. 		   otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT || 342. 		   otmp->otyp == GAUNTLETS_OF_FUMBLING || 343. 		   !rn2(11))) { 344. 			curse(otmp); 345. 			otmp->spe = -rne(2); 346. 		} else if(!rn2(10)) { 347. 			otmp->spe = rne(2); 348. 			otmp->blessed = rn2(2); 349. 		} else	blessorcurse(otmp, 10); 350. 		if(otmp->otyp == DRAGON_SCALE_MAIL) 351. 			otmp->corpsenm = PM_GREY_DRAGON + 352. 			    rn2(PM_YELLOW_DRAGON-PM_GREY_DRAGON+1); 353. 		break; 354. 	case WAND_SYM: 355. #ifdef HARD 356. 		if(otmp->otyp == WAN_WISHING) otmp->spe = rnd(3); else 357. #else 358. 		if(otmp->otyp == WAN_WISHING) otmp->spe = 3; else 359. #endif 360. 		otmp->spe = rn1(5,  361.  			(objects[otmp->otyp].bits & NODIR) ? 11 : 4); 362. 		blessorcurse(otmp, 17); 363. 		otmp->recharged = 0; /* used to control recharging */ 364. 		break; 365. 	case RING_SYM: 366. 		if(objects[otmp->otyp].oc_charged) { 367. 		    blessorcurse(otmp, 3); 368. 		    if(rn2(10)) { 369. 			if(rn2(10) && bcsign(otmp)) 370. 			    otmp->spe = bcsign(otmp) * rne(3); 371. 			else otmp->spe = rn2(2) ? rne(3) : -rne(3); 372. 		    }  373.  		    if (otmp->spe < 0 && rn2(5)) curse(otmp); 374. 		} else if(rn2(10) && (otmp->otyp == RIN_TELEPORTATION || 375. #ifdef POLYSELF 376. 			  otmp->otyp == RIN_POLYMORPH || 377. #endif 378. 			  otmp->otyp == RIN_AGGRAVATE_MONSTER || 379. 			  otmp->otyp == RIN_HUNGER || !rn2(9))) { 380. 			curse(otmp); 381. 		}  382.  		break; 383. 	case ROCK_SYM: 384. 		switch (otmp->otyp) { 385. 		    case STATUE: 386. 			/* contains book? */ 387.  			otmp->spe = (rn2(dlevel/2 + 10) > 10); 388. 			/* overridden by mkstatue */ 389. 			otmp->corpsenm = rndmonnum; 390. 			otmp->owt = mons[otmp->corpsenm].cwt; 391. 		}  392.  		break; 393. 	default: 394. 		impossible("impossible mkobj %d, sym '%c'.", otmp->otyp, let); 395. 		return (struct obj *)0; 396. 	}  397.  	otmp->owt = weight(otmp); 398. 	return(otmp); 399. }  400.   401.  void 402. bless(otmp) 403. register struct obj *otmp; 404. {  405.  	otmp->cursed = 0; 406. 	otmp->blessed = 1; 407. 	return; 408. }  409.   410.  void 411. curse(otmp) 412. register struct obj *otmp; 413. {  414.  	otmp->blessed = 0; 415. 	otmp->cursed = 1; 416. 	return; 417. }  418.   419.  void 420. blessorcurse(otmp, chance) 421. register struct obj *otmp; 422. register int chance; 423. {  424.  	if(otmp->blessed || otmp->cursed) return; 425.  426.  	if(!rn2(chance)) 427. 	    if(!rn2(2) || Inhell) { /* in hell, don't usually bless items */ 428. 		curse(otmp); 429. 	    } else { 430. 		bless(otmp); 431. 	    }  432.  	return; 433. }  434.   435.  int 436. bcsign(otmp) 437. register struct obj *otmp; 438. {  439.  	return(!!otmp->blessed - !!otmp->cursed); 440. }  441.   442.  int 443. letter(c) { 444. 	return(('@' <= c && c <= 'Z') || ('a' <= c && c <= 'z')); 445. }  446.   447.  int 448. weight(obj) 449. register struct obj *obj; 450. {  451.  	register int wt = objects[obj->otyp].oc_weight; 452.  453.  	if (Is_container(obj)) { 454. 		struct obj *contents; 455. 		for(contents=fcobj; contents; contents=contents->nobj) { 456. 			if (contents->cobj == obj) 457. 				inc_cwt(obj, contents); 458. 		}  459.  		return obj->owt; 460. 	}  461.  	if (obj->otyp == CORPSE && obj->corpsenm > -1) 462. 		return obj->quan * mons[obj->corpsenm].cwt; 463. 	else if (obj->otyp == STATUE && obj->corpsenm > -1) 464. 		return obj->quan * (mons[obj->corpsenm].cwt * 3 / 2); 465. 	return(wt ? wt*obj->quan : (obj->quan + 1)>>1); 466. }  467.   468.  void 469. mkgold(num,x,y) 470. long num; 471. int x, y;  472. { 473.  	register struct gold *gold; 474. 	register long amount = (num ? num : 1 + (rnd(dlevel+2) * rnd(30))); 475.  476.  	if(levl[x][y].gmask) { 477. 		gold = g_at(x,y); 478. 		gold->amount += amount; 479. 	} else { 480. 		gold = newgold; 481. 		gold->ngold = fgold; 482. 		gold->gx = x;  483. gold->gy = y; 484. gold->amount = amount; 485. 		fgold = gold; 486. 		levl[x][y].gmask = 1; 487. 		/* do sth with display? */ 488.  	}  489.  	return; 490. }  491.   492.  struct obj * 493. mkcorpse_at(ptr, x, y)  494. register struct permonst *ptr; 495. int	x, y;  496. { 497.  	register struct obj *otmp; 498.  499.  	otmp = mksobj_at(CORPSE, x, y); 500. 	if(otmp)  { 501. 		otmp->corpsenm = monsndx(ptr); 502. 		otmp->owt = ptr->cwt; 503. 	}  504.  	return(otmp); 505. }  506.   507.  struct obj * 508. mk_tt_corpse(x, y)  509. register int x, y; 510. { 511.  	register struct obj *otmp; 512.  513.  	if((otmp = mksobj(CORPSE,FALSE))) { 514. 		otmp->ox = x;  515. otmp->oy = y; 516. if(otmp = tt_oname(otmp)) { 517. 			otmp->nobj = fobj; 518. 			fobj = otmp; 519. 			levl[x][y].omask = 1; 520. 		}  521.  	}  522.  	return(otmp); 523. }  524.   525.  struct obj * 526. mkstatue(ptr, x, y)  527. register struct permonst *ptr; 528. int x, y;  529. { 530.  	register struct obj *otmp; 531.  532.  	if((otmp = mksobj_at(STATUE, x, y))) { 533.  534.  	    if(ptr)	otmp->corpsenm = monsndx(ptr); 535. 	    else	otmp->corpsenm = rndmonnum; 536. 	}  537.  	return(otmp); 538. }  539.   540.  struct obj * 541. mk_named_object(objtype, ptr, x, y, nm, lth) 542. int objtype; /* CORPSE or STATUE */ 543. register struct permonst *ptr; 544. int x, y;  545. char * nm; 546. register int lth; 547. {  548.  	struct obj *otmp; 549. 	register struct obj *obj2; 550.  551.  	if (lth == 0) { 552. 		switch(objtype) { 553. 			case STATUE: return (mkstatue(ptr, x, y)); 554. 			case CORPSE: return (mkcorpse_at(ptr, x, y)); 555. 			default: impossible("making named type %d", objtype); 556. 				return mksobj_at(objtype, x, y); 557. 		}  558.  	}  559.   560.  	if((otmp = mksobj(objtype,FALSE))) { 561. 		obj2 = newobj(lth); 562. 		*obj2 = *otmp; 563. 		obj2->corpsenm = monsndx(ptr); 564. 		obj2->owt = ptr->cwt; 565. 		obj2->onamelth = lth; 566. 		Strcpy (ONAME(obj2), nm); 567. 		free( (genericptr_t)otmp); 568. 		obj2->ox = x;  569. obj2->oy = y; 570. obj2->nobj = fobj; 571. 		fobj = obj2; 572. 		levl[x][y].omask = 1; 573. 		return(obj2); 574. 	} else  return((struct obj *)0); 575. }  576.   577.  #ifdef MEDUSA 578. struct obj * 579. mk_tt_statue(x, y)  580. register int x, y; 581. { 582.  	register struct obj *otmp; 583.  584.  	if((otmp = mksobj(STATUE,FALSE))) { 585. 		otmp->ox = x;  586. otmp->oy = y; 587. if(otmp = tt_oname(otmp)) { 588. 			otmp->nobj = fobj; 589. 			fobj = otmp; 590. 			levl[x][y].omask = 1; 591. 			otmp->spe = 0; 592. 			/* player statues never contain books */ 593. 		}  594.  	}  595.  	return(otmp); 596. }  597.  #endif 598.  599.  boolean 600. is_flammable(otmp) 601. register struct obj *otmp; 602. {  603.  	return((objects[otmp->otyp].oc_material == WOOD || 604. 			objects[otmp->otyp].oc_material == 0)); 605.  606.  }  607.   608.  boolean 609. is_rustprone(otmp) 610. register struct obj *otmp; 611. {  612.  	return(objects[otmp->otyp].oc_material == METAL); 613. }  614.   615.  void 616. set_omask(x, y)  617. register xchar x, y; 618. { 619.  	levl[x][y].gmask = (g_at(x, y) != (struct gold *)0); 620. 	levl[x][y].omask = (o_at(x, y) != (struct obj *)0); 621. }