Source:NetHack 3.0.0/weapon.c

From NetHackWiki
(Redirected from NetHack 3.0.0/weapon.c)
Jump to navigation Jump to search

Below is the full text to weapon.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/weapon.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: @(#)weapon.c	3.0	89/04/24
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    /*
6.     *	This module contains code for calculation of "to hit" and damage
7.     *	bonuses for any given weapon used, as well as weapons selection
8.     *	code for monsters.
9.     */
10.   #include	"hack.h"
11.   
12.   static const char kebabable[] = { S_XORN, S_DRAGON, S_NAGA, S_GIANT, 0 };
13.   
14.   /*
15.    * 	hitval returns an integer representing the "to hit" bonuses
16.    *	of "otmp" against the monster type "ptr".
17.    */
18.   int
19.   hitval(otmp, ptr)
20.   struct	obj *otmp;
21.   struct	permonst *ptr;
22.   {
23.   	int	tmp = 0;
24.   
25.   	if(otmp->olet == WEAPON_SYM || otmp->otyp == PICK_AXE)
26.   		tmp += otmp->spe;
27.   
28.   /*	Put weapon specific "to hit" bonuses in below:		*/
29.   	switch(otmp->otyp) {
30.   
31.   #ifdef TOLKIEN
32.   	    case DWARVISH_MATTOCK:
33.   #endif
34.   	    case TWO_HANDED_SWORD:	tmp -= 1; break;
35.   	    case KATANA:		tmp += 1; break;
36.   #ifdef TOLKIEN
37.   	    case ELVEN_DAGGER:
38.   	    case ORCISH_DAGGER:
39.   #endif
40.   	    case DAGGER:
41.   	    case SHURIKEN:		tmp += 2; break;
42.   #ifdef WORM
43.   	    case CRYSKNIFE:		tmp += 3; break;
44.   #endif
45.   	}
46.   
47.   /*	Put weapon vs. monster type "to hit" bonuses in below:	*/
48.   
49.   	/* Blessed weapons used against undead or demons */
50.   	if(otmp->olet == WEAPON_SYM && otmp->blessed &&
51.   	   (is_demon(ptr) || is_undead(ptr))) tmp += 2;
52.   
53.   	if(otmp->otyp >= SPEAR && otmp->otyp <= JAVELIN &&
54.   	   index(kebabable, ptr->mlet)) tmp += 2;
55.   
56.   /*	Put specially named weapon "to hit" bonuses in below:	*/
57.   #ifdef NAMED_ITEMS
58.   	tmp += spec_abon(otmp, ptr);
59.   #endif
60.   	return(tmp);
61.   }
62.   
63.   /*
64.    * 	dmgval returns an integer representing the damage bonuses
65.    *	of "otmp" against the monster type "ptr".
66.    */
67.   int
68.   dmgval(otmp, ptr)
69.   struct	obj *otmp;
70.   struct	permonst *ptr;
71.   {
72.   	int	tmp = 0;
73.   
74.   	if(otmp->otyp == CREAM_PIE)	return(0);
75.   
76.   	if(bigmonst(ptr)) {
77.   	    if(objects[otmp->otyp].wldam)
78.   		tmp = rnd(objects[otmp->otyp].wldam);
79.   	    switch (otmp->otyp) {
80.   		case CROSSBOW_BOLT:
81.   		case MORNING_STAR:
82.   		case PARTISAN:
83.   #ifdef TOLKIEN
84.   		case ELVEN_BROADSWORD:
85.   #endif
86.   		case BROADSWORD:	tmp += 1; break;
87.   
88.   		case FLAIL:
89.   		case RANSEUR:
90.   		case VOULGE:		tmp += rnd(4); break;
91.   
92.   		case ACID_VENOM:
93.   		case HALBERD:
94.   		case SPETUM:		tmp += rnd(6); break;
95.   
96.   		case BARDICHE:
97.   		case TRIDENT:		tmp += d(2,4); break;
98.   
99.   #ifdef TOLKIEN
100.  		case DWARVISH_MATTOCK:
101.  #endif
102.  		case TWO_HANDED_SWORD:	tmp += d(2,6); break;
103.  	    }
104.  	} else {
105.  	    if(objects[otmp->otyp].wsdam)
106.  		tmp = rnd(objects[otmp->otyp].wsdam);
107.  	    switch (otmp->otyp) {
108.  		case CROSSBOW_BOLT:
109.  		case MACE:
110.  		case FLAIL:
111.  		case SPETUM:
112.  		case TRIDENT:		tmp += 1; break;
113.  
114.  		case BARDICHE:
115.  		case BILL_GUISARME:
116.  		case GUISARME:
117.  		case LUCERN_HAMMER:
118.  		case MORNING_STAR:
119.  		case RANSEUR:
120.  		case BROADSWORD:
121.  #ifdef TOLKIEN
122.  		case ELVEN_BROADSWORD:
123.  #endif
124.  		case VOULGE:		tmp += rnd(4); break;
125.  
126.  		case ACID_VENOM:	tmp += rnd(6); break;
127.  	    }
128.  	}
129.  	if (otmp->otyp == BULLWHIP && thick_skinned(ptr))
130.  		/* thick skinned/scaled creatures don't feel it */
131.  		tmp = 0;
132.  	if (otmp->olet == WEAPON_SYM || otmp->otyp == PICK_AXE)
133.  		tmp += otmp->spe;
134.  
135.  /*	Put weapon vs. monster type damage bonuses in below:	*/
136.  	if(otmp->olet == WEAPON_SYM) {
137.  	    if (otmp->blessed && (is_undead(ptr) || is_demon(ptr)))
138.  		tmp += rnd(4);
139.  	}
140.  
141.  /*	Put specially named weapon damage bonuses in below:	*/
142.  #ifdef NAMED_ITEMS
143.  	tmp += spec_dbon(otmp, ptr, tmp);
144.  #endif
145.  	return(tmp);
146.  }
147.  
148.  void
149.  set_uasmon() {		/* update the "uasmon" structure */
150.  
151.  #ifdef POLYSELF
152.  	if(u.umonnum >= 0) uasmon = &mons[u.umonnum];
153.  	else {
154.  #endif
155.  
156.  		uasmon = &playermon;
157.  		playermon.mlevel = u.ulevel;
158.  		playermon.ac = u.uac;
159.  		playermon.mr = (u.ulevel > 8) ? 5 * (u.ulevel-7) : u.ulevel;
160.  #ifdef POLYSELF
161.  	}
162.  #endif
163.  	return;
164.  }
165.  
166.  #define	Oselect(x)	if((otmp = m_carrying(mtmp, x))) return(otmp);
167.  
168.  #ifdef TOLKIEN
169.  static const int rwep[] =
170.  	{ DWARVISH_SPEAR, ELVEN_SPEAR, SPEAR, ORCISH_SPEAR, JAVELIN,
171.  	  SHURIKEN, ELVEN_ARROW, ARROW, ORCISH_ARROW, CROSSBOW_BOLT,
172.  	  ELVEN_DAGGER, DAGGER, ORCISH_DAGGER, KNIFE, ROCK, LOADSTONE,
173.  	  LUCKSTONE, DART, BOOMERANG, CREAM_PIE
174.  	  /* note: CREAM_PIE should NOT be #ifdef KOPS */
175.  	  };
176.  #else
177.  static const int rwep[] =
178.  	{ SPEAR, JAVELIN, SHURIKEN, ARROW, CROSSBOW_BOLT, DAGGER, KNIFE,
179.  	  ROCK, LOADSTONE, LUCKSTONE, DART, BOOMERANG, CREAM_PIE
180.  	  /* note: CREAM_PIE should NOT be #ifdef KOPS */
181.  	  };
182.  #endif
183.  
184.  struct obj *
185.  select_rwep(mtmp)	/* select a ranged weapon for the monster */
186.  register struct monst *mtmp;
187.  {
188.  	register struct obj *otmp;
189.  	int i;
190.  #ifdef KOPS
191.  	char mlet = mtmp->data->mlet;
192.  
193.  	if(mlet == S_KOP)	/* pies are first choice for Kops */
194.  	    Oselect(CREAM_PIE);
195.  #endif
196.  	if(throws_rocks(mtmp->data))	/* ...boulders for giants */
197.  	    Oselect(BOULDER);
198.  	/*
199.  	 * other than these two specific cases, always select the
200.  	 * most potent ranged weapon to hand.
201.  	 */
202.  	for (i = 0; i < SIZE(rwep); i++) {
203.  	    boolean no_propellor = FALSE;
204.  	    int prop;
205.  
206.  	    /* shooting gems from slings; this goes just before the darts */
207.  	    if (rwep[i]==DART && !likes_gems(mtmp->data)
208.  			/* && m_carrying(mtmp, SLING) */) {
209.  		for(otmp=mtmp->minvent; otmp; otmp=otmp->nobj) {
210.  		    if(otmp->olet==GEM_SYM &&
211.  				(otmp->otyp != LOADSTONE || !otmp->cursed))
212.  			return(otmp);
213.  		}
214.  	    }
215.  	    prop = (objects[rwep[i]]).w_propellor;
216.  	    if (prop > 0) {
217.  		switch (prop) {
218.  		case WP_BOW:
219.  #ifdef TOLKIEN
220.  		  no_propellor = !(m_carrying(mtmp, BOW) ||
221.  				   m_carrying(mtmp, ELVEN_BOW) ||
222.  				   m_carrying(mtmp, ORCISH_BOW));
223.  #else
224.  		  no_propellor = !(m_carrying(mtmp, BOW));
225.  #endif
226.  		  break;
227.  		/* case WP_SLING:
228.  		  no_propellor = (m_carrying(mtmp, SLING) != 0);
229.  		  break; */
230.  		case WP_CROSSBOW:
231.  		  no_propellor = (m_carrying(mtmp, CROSSBOW) != 0);
232.  		}
233.  	      }
234.  	    if (!no_propellor) Oselect(rwep[i]);
235.  	  }
236.  
237.  	/* failure */
238.  	return (struct obj *)0;
239.  }
240.  
241.  #ifdef TOLKIEN
242.  /* 0 = used by any monster; 1 = only used by strong monsters */
243.  static const int hwep[][2] =
244.  	{ {DWARVISH_MATTOCK,1}, {TWO_HANDED_SWORD,1}, {KATANA,0},
245.  #ifdef WORM
246.  	  {CRYSKNIFE,0},
247.  #endif
248.  	  {TRIDENT,0}, {LONG_SWORD,0}, {ELVEN_BROADSWORD,0}, {BROADSWORD,0},
249.  	  {LUCERN_HAMMER,1}, {SCIMITAR,1}, {HALBERD,1}, {PARTISAN,1},
250.  	  {LANCE,1}, {FAUCHARD,1}, {BILL_GUISARME,1}, {BEC_DE_CORBIN,1},
251.  	  {GUISARME,1}, {RANSEUR,1}, {SPETUM,1}, {VOULGE,1}, {BARDICHE,0},
252.  	  {MORNING_STAR,0}, {GLAIVE,0}, {ELVEN_SHORT_SWORD,0},
253.  	  {DWARVISH_SHORT_SWORD,0}, {SHORT_SWORD,0}, {ORCISH_SHORT_SWORD,0},
254.  	  {MACE,0}, {AXE,0}, {DWARVISH_SPEAR,0}, {ELVEN_SPEAR,0}, {SPEAR,0},
255.  	  {ORCISH_SPEAR,0}, {FLAIL,0}, {QUARTERSTAFF,1}, {JAVELIN,0},
256.  	  {AKLYS,0}, {CLUB,0}, {PICK_AXE,0},
257.  #ifdef KOPS
258.  	  {RUBBER_HOSE,0},
259.  #endif /* KOPS */
260.  	  {ELVEN_DAGGER,0}, {DAGGER,0}, {ORCISH_DAGGER,0}, {SCALPEL,0},
261.  	  {KNIFE,0},
262.  #ifdef WORM
263.  	  {WORM_TOOTH,0},
264.  #endif
265.  	  {BULLWHIP,0}
266.  	};
267.  #else /* TOLKIEN */
268.  /* 0 = used by any monster; 1 = only used by strong monsters */
269.  static const int hwep[][2] =
270.  	{ {TWO_HANDED_SWORD,1}, {KATANA,0},
271.  #ifdef WORM
272.  	  {CRYSKNIFE,0},
273.  #endif
274.  	  {TRIDENT,0}, {LONG_SWORD,0}, {BROADSWORD,0}, {LUCERN_HAMMER,1},
275.  	  {SCIMITAR,1}, {HALBERD,1}, {PARTISAN,1}, {LANCE,1}, {FAUCHARD,1},
276.  	  {BILL_GUISARME,1}, {BEC_DE_CORBIN,1}, {GUISARME,1}, {RANSEUR,1},
277.  	  {SPETUM,1}, {VOULGE,1}, {BARDICHE,0}, {MORNING_STAR,0}, {GLAIVE,0},
278.  	  {SHORT_SWORD,0}, {MACE,0}, {AXE,0}, {SPEAR,0}, {FLAIL,0},
279.  	  {QUARTERSTAFF,1}, {JAVELIN,0}, {AKLYS,0}, {CLUB,0}, {PICK_AXE,0},
280.  #ifdef KOPS
281.  	  {RUBBER_HOSE,0},
282.  #endif /* KOPS */
283.  	  {DAGGER,0}, {SCALPEL,0}, {KNIFE,0},
284.  #ifdef WORM
285.  	  {WORM_TOOTH,0},
286.  #endif
287.  	  {BULLWHIP,0}
288.  	};
289.  #endif /* TOLKIEN */
290.  
291.  struct obj *
292.  select_hwep(mtmp)	/* select a hand to hand weapon for the monster */
293.  register struct monst *mtmp;
294.  {
295.  	register struct obj *otmp;
296.  	int i;
297.  	boolean strong = strongmonst(mtmp->data);
298.  
299.  	if(is_giant(mtmp->data))	/* giants just love to use clubs */
300.  	    Oselect(CLUB);
301.  
302.  	/* only strong monsters can wield big (esp. long) weapons */
303.  	/* all monsters can wield the remaining weapons */
304.  	for (i = 0; i < SIZE(hwep); i++)
305.  	    if (strong || hwep[i][1]==0)
306.  		Oselect(hwep[i][0]);
307.  
308.  	/* failure */
309.  	return (struct obj *)0;
310.  }
311.  
312.  int
313.  abon() {	/* attack bonus for strength & dexterity */
314.  	int	sbon;
315.  
316.  #ifdef POLYSELF
317.  	if (u.umonnum >= 0) return(adj_lev(&mons[u.umonnum])-3);
318.  #endif
319.  	if(ACURR(A_STR) < 6) sbon = -2;
320.  	else if(ACURR(A_STR) < 8) sbon = -1;
321.  	else if(ACURR(A_STR) < 17) sbon = 0;
322.  	else if(ACURR(A_STR) < 69) sbon = 1;	/* up to 18/50 */
323.  	else if(ACURR(A_STR) < 118) sbon = 2;
324.  	else sbon = 3;
325.  
326.  	if(ACURR(A_DEX) < 4) return(sbon-3);
327.  	else if(ACURR(A_DEX) < 6) return(sbon-2);
328.  	else if(ACURR(A_DEX) < 8) return(sbon-1);
329.  	else if(ACURR(A_DEX) < 14) return(sbon);
330.  	else return(sbon+ACURR(A_DEX)-15);
331.  }
332.  
333.  int
334.  dbon() {	/* damage bonus for strength */
335.  #ifdef POLYSELF
336.  	if (u.umonnum >= 0) return(0);
337.  #endif
338.  
339.  	if(ACURR(A_STR) < 6) return(-1);
340.  	else if(ACURR(A_STR) < 16) return(0);
341.  	else if(ACURR(A_STR) < 18) return(1);
342.  	else if(ACURR(A_STR) == 18) return(2);		/* up to 18 */
343.  	else if(ACURR(A_STR) < 94) return(3);		/* up to 18/75 */
344.  	else if(ACURR(A_STR) < 109) return(4);		/* up to 18/90 */
345.  	else if(ACURR(A_STR) < 118) return(5);	/* up to 18/99 */
346.  	else return(6);
347.  }