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