Source:NetHack 3.0.0/mkobj.c

From NetHackWiki
Revision as of 04:55, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/mkobj.c moved to Source:NetHack 3.0.0/mkobj.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

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.  }