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