xref: /netbsd/games/hack/hack.steal.c (revision bf9ec67e)
1 /*	$NetBSD: hack.steal.c,v 1.4 1997/10/19 16:59:04 christos Exp $	*/
2 
3 /*
4  * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
5  */
6 
7 #include <sys/cdefs.h>
8 #ifndef lint
9 __RCSID("$NetBSD: hack.steal.c,v 1.4 1997/10/19 16:59:04 christos Exp $");
10 #endif				/* not lint */
11 
12 #include <stdlib.h>
13 #include "hack.h"
14 #include "extern.h"
15 
16 long				/* actually returns something that fits in an
17 				 * int */
18 somegold()
19 {
20 	return ((u.ugold < 100) ? u.ugold :
21 		(u.ugold > 10000) ? rnd(10000) : rnd((int) u.ugold));
22 }
23 
24 void
25 stealgold(mtmp)
26 	struct monst   *mtmp;
27 {
28 	struct gold    *gold = g_at(u.ux, u.uy);
29 	long            tmp;
30 	if (gold && (!u.ugold || gold->amount > u.ugold || !rn2(5))) {
31 		mtmp->mgold += gold->amount;
32 		freegold(gold);
33 		if (Invisible)
34 			newsym(u.ux, u.uy);
35 		pline("%s quickly snatches some gold from between your feet!",
36 		      Monnam(mtmp));
37 		if (!u.ugold || !rn2(5)) {
38 			rloc(mtmp);
39 			mtmp->mflee = 1;
40 		}
41 	} else if (u.ugold) {
42 		u.ugold -= (tmp = somegold());
43 		pline("Your purse feels lighter.");
44 		mtmp->mgold += tmp;
45 		rloc(mtmp);
46 		mtmp->mflee = 1;
47 		flags.botl = 1;
48 	}
49 }
50 
51 /* steal armor after he finishes taking it off */
52 unsigned        stealoid;	/* object to be stolen */
53 unsigned        stealmid;	/* monster doing the stealing */
54 int
55 stealarm()
56 {
57 	struct monst   *mtmp;
58 	struct obj     *otmp;
59 
60 	for (otmp = invent; otmp; otmp = otmp->nobj)
61 		if (otmp->o_id == stealoid) {
62 			for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
63 				if (mtmp->m_id == stealmid) {
64 					if (dist(mtmp->mx, mtmp->my) < 3) {
65 						freeinv(otmp);
66 						pline("%s steals %s!", Monnam(mtmp), doname(otmp));
67 						mpickobj(mtmp, otmp);
68 						mtmp->mflee = 1;
69 						rloc(mtmp);
70 					}
71 					break;
72 				}
73 			break;
74 		}
75 	stealoid = 0;
76 	return 0;
77 }
78 
79 /* returns 1 when something was stolen */
80 /* (or at least, when N should flee now) */
81 /* avoid stealing the object stealoid */
82 int
83 steal(mtmp)
84 	struct monst   *mtmp;
85 {
86 	struct obj     *otmp;
87 	int		tmp;
88 	int		named = 0;
89 
90 	if (!invent) {
91 		if (Blind)
92 			pline("Somebody tries to rob you, but finds nothing to steal.");
93 		else
94 			pline("%s tries to rob you, but she finds nothing to steal!",
95 			      Monnam(mtmp));
96 		return (1);	/* let her flee */
97 	}
98 	tmp = 0;
99 	for (otmp = invent; otmp; otmp = otmp->nobj)
100 		if (otmp != uarm2)
101 			tmp += ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1);
102 	tmp = rn2(tmp);
103 	for (otmp = invent; otmp; otmp = otmp->nobj)
104 		if (otmp != uarm2)
105 			if ((tmp -= ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1))
106 			    < 0)
107 				break;
108 	if (!otmp) {
109 		impossible("Steal fails!");
110 		return (0);
111 	}
112 	if (otmp->o_id == stealoid)
113 		return (0);
114 	if ((otmp->owornmask & (W_ARMOR | W_RING))) {
115 		switch (otmp->olet) {
116 		case RING_SYM:
117 			ringoff(otmp);
118 			break;
119 		case ARMOR_SYM:
120 			if (multi < 0 || otmp == uarms) {
121 				setworn((struct obj *) 0, otmp->owornmask & W_ARMOR);
122 				break;
123 			} {
124 				int             curssv = otmp->cursed;
125 				otmp->cursed = 0;
126 				stop_occupation();
127 				pline("%s seduces you and %s off your %s.",
128 				      Amonnam(mtmp, Blind ? "gentle" : "beautiful"),
129 				      otmp->cursed ? "helps you to take"
130 				      : "you start taking",
131 				      (otmp == uarmg) ? "gloves" :
132 				      (otmp == uarmh) ? "helmet" : "armor");
133 				named++;
134 				(void) armoroff(otmp);
135 				otmp->cursed = curssv;
136 				if (multi < 0) {
137 					/*
138 					multi = 0;
139 					nomovemsg = 0;
140 					afternmv = 0;
141 					*/
142 					stealoid = otmp->o_id;
143 					stealmid = mtmp->m_id;
144 					afternmv = stealarm;
145 					return (0);
146 				}
147 				break;
148 			}
149 		default:
150 			impossible("Tried to steal a strange worn thing.");
151 		}
152 	} else if (otmp == uwep)
153 		setuwep((struct obj *) 0);
154 	if (otmp->olet == CHAIN_SYM) {
155 		impossible("How come you are carrying that chain?");
156 	}
157 	if (Punished && otmp == uball) {
158 		Punished = 0;
159 		freeobj(uchain);
160 		free((char *) uchain);
161 		uchain = (struct obj *) 0;
162 		uball->spe = 0;
163 		uball = (struct obj *) 0;	/* superfluous */
164 	}
165 	freeinv(otmp);
166 	pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp));
167 	mpickobj(mtmp, otmp);
168 	return ((multi < 0) ? 0 : 1);
169 }
170 
171 void
172 mpickobj(mtmp, otmp)
173 	struct monst   *mtmp;
174 	struct obj     *otmp;
175 {
176 	otmp->nobj = mtmp->minvent;
177 	mtmp->minvent = otmp;
178 }
179 
180 int
181 stealamulet(mtmp)
182 	struct monst   *mtmp;
183 {
184 	struct obj     *otmp;
185 
186 	for (otmp = invent; otmp; otmp = otmp->nobj) {
187 		if (otmp->olet == AMULET_SYM) {
188 			/* might be an imitation one */
189 			if (otmp == uwep)
190 				setuwep((struct obj *) 0);
191 			freeinv(otmp);
192 			mpickobj(mtmp, otmp);
193 			pline("%s stole %s!", Monnam(mtmp), doname(otmp));
194 			return (1);
195 		}
196 	}
197 	return (0);
198 }
199 
200 /* release the objects the killed animal has stolen */
201 void
202 relobj(mtmp, show)
203 	struct monst   *mtmp;
204 	int show;
205 {
206 	struct obj     *otmp, *otmp2;
207 
208 	for (otmp = mtmp->minvent; otmp; otmp = otmp2) {
209 		otmp->ox = mtmp->mx;
210 		otmp->oy = mtmp->my;
211 		otmp2 = otmp->nobj;
212 		otmp->nobj = fobj;
213 		fobj = otmp;
214 		stackobj(fobj);
215 		if (show & cansee(mtmp->mx, mtmp->my))
216 			atl(otmp->ox, otmp->oy, otmp->olet);
217 	}
218 	mtmp->minvent = (struct obj *) 0;
219 	if (mtmp->mgold || mtmp->data->mlet == 'L') {
220 		long            tmp;
221 
222 		tmp = (mtmp->mgold > 10000) ? 10000 : mtmp->mgold;
223 		mkgold((long) (tmp + d(dlevel, 30)), mtmp->mx, mtmp->my);
224 		if (show & cansee(mtmp->mx, mtmp->my))
225 			atl(mtmp->mx, mtmp->my, '$');
226 	}
227 }
228