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