games: Massive style(9) cleanup commit. Reduces differences to NetBSD.
[games.git] / games / hack / hack.steal.c
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 }