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