Home | History | Annotate | Line # | Download | only in hack
hack.steal.c revision 1.6
      1 /*	$NetBSD: hack.steal.c,v 1.6 2009/06/07 18:30:39 dholland Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
      5  * Amsterdam
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions are
     10  * met:
     11  *
     12  * - Redistributions of source code must retain the above copyright notice,
     13  * this list of conditions and the following disclaimer.
     14  *
     15  * - Redistributions in binary form must reproduce the above copyright
     16  * notice, this list of conditions and the following disclaimer in the
     17  * documentation and/or other materials provided with the distribution.
     18  *
     19  * - Neither the name of the Stichting Centrum voor Wiskunde en
     20  * Informatica, nor the names of its contributors may be used to endorse or
     21  * promote products derived from this software without specific prior
     22  * written permission.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     25  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     26  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     27  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
     28  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     29  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     30  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     31  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     32  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     33  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     34  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     35  */
     36 
     37 /*
     38  * Copyright (c) 1982 Jay Fenlason <hack (at) gnu.org>
     39  * All rights reserved.
     40  *
     41  * Redistribution and use in source and binary forms, with or without
     42  * modification, are permitted provided that the following conditions
     43  * are met:
     44  * 1. Redistributions of source code must retain the above copyright
     45  *    notice, this list of conditions and the following disclaimer.
     46  * 2. Redistributions in binary form must reproduce the above copyright
     47  *    notice, this list of conditions and the following disclaimer in the
     48  *    documentation and/or other materials provided with the distribution.
     49  * 3. The name of the author may not be used to endorse or promote products
     50  *    derived from this software without specific prior written permission.
     51  *
     52  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
     53  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
     54  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
     55  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     56  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     57  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     58  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     59  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     60  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     61  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     62  */
     63 
     64 #include <sys/cdefs.h>
     65 #ifndef lint
     66 __RCSID("$NetBSD: hack.steal.c,v 1.6 2009/06/07 18:30:39 dholland Exp $");
     67 #endif				/* not lint */
     68 
     69 #include <stdlib.h>
     70 #include "hack.h"
     71 #include "extern.h"
     72 
     73 /*
     74  * actually returns something that fits in an int
     75  */
     76 long
     77 somegold(void)
     78 {
     79 	return ((u.ugold < 100) ? u.ugold :
     80 		(u.ugold > 10000) ? rnd(10000) : rnd((int) u.ugold));
     81 }
     82 
     83 void
     84 stealgold(struct monst *mtmp)
     85 {
     86 	struct gold    *gold = g_at(u.ux, u.uy);
     87 	long            tmp;
     88 	if (gold && (!u.ugold || gold->amount > u.ugold || !rn2(5))) {
     89 		mtmp->mgold += gold->amount;
     90 		freegold(gold);
     91 		if (Invisible)
     92 			newsym(u.ux, u.uy);
     93 		pline("%s quickly snatches some gold from between your feet!",
     94 		      Monnam(mtmp));
     95 		if (!u.ugold || !rn2(5)) {
     96 			rloc(mtmp);
     97 			mtmp->mflee = 1;
     98 		}
     99 	} else if (u.ugold) {
    100 		u.ugold -= (tmp = somegold());
    101 		pline("Your purse feels lighter.");
    102 		mtmp->mgold += tmp;
    103 		rloc(mtmp);
    104 		mtmp->mflee = 1;
    105 		flags.botl = 1;
    106 	}
    107 }
    108 
    109 /* steal armor after he finishes taking it off */
    110 unsigned        stealoid;	/* object to be stolen */
    111 unsigned        stealmid;	/* monster doing the stealing */
    112 int
    113 stealarm(void)
    114 {
    115 	struct monst   *mtmp;
    116 	struct obj     *otmp;
    117 
    118 	for (otmp = invent; otmp; otmp = otmp->nobj)
    119 		if (otmp->o_id == stealoid) {
    120 			for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
    121 				if (mtmp->m_id == stealmid) {
    122 					if (dist(mtmp->mx, mtmp->my) < 3) {
    123 						freeinv(otmp);
    124 						pline("%s steals %s!", Monnam(mtmp), doname(otmp));
    125 						mpickobj(mtmp, otmp);
    126 						mtmp->mflee = 1;
    127 						rloc(mtmp);
    128 					}
    129 					break;
    130 				}
    131 			break;
    132 		}
    133 	stealoid = 0;
    134 	return 0;
    135 }
    136 
    137 /* returns 1 when something was stolen */
    138 /* (or at least, when N should flee now) */
    139 /* avoid stealing the object stealoid */
    140 int
    141 steal(struct monst *mtmp)
    142 {
    143 	struct obj     *otmp;
    144 	int		tmp;
    145 	int		named = 0;
    146 
    147 	if (!invent) {
    148 		if (Blind)
    149 			pline("Somebody tries to rob you, but finds nothing to steal.");
    150 		else
    151 			pline("%s tries to rob you, but she finds nothing to steal!",
    152 			      Monnam(mtmp));
    153 		return (1);	/* let her flee */
    154 	}
    155 	tmp = 0;
    156 	for (otmp = invent; otmp; otmp = otmp->nobj)
    157 		if (otmp != uarm2)
    158 			tmp += ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1);
    159 	tmp = rn2(tmp);
    160 	for (otmp = invent; otmp; otmp = otmp->nobj)
    161 		if (otmp != uarm2)
    162 			if ((tmp -= ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1))
    163 			    < 0)
    164 				break;
    165 	if (!otmp) {
    166 		impossible("Steal fails!");
    167 		return (0);
    168 	}
    169 	if (otmp->o_id == stealoid)
    170 		return (0);
    171 	if ((otmp->owornmask & (W_ARMOR | W_RING))) {
    172 		switch (otmp->olet) {
    173 		case RING_SYM:
    174 			ringoff(otmp);
    175 			break;
    176 		case ARMOR_SYM:
    177 			if (multi < 0 || otmp == uarms) {
    178 				setworn((struct obj *) 0, otmp->owornmask & W_ARMOR);
    179 				break;
    180 			} {
    181 				int             curssv = otmp->cursed;
    182 				otmp->cursed = 0;
    183 				stop_occupation();
    184 				pline("%s seduces you and %s off your %s.",
    185 				      Amonnam(mtmp, Blind ? "gentle" : "beautiful"),
    186 				      otmp->cursed ? "helps you to take"
    187 				      : "you start taking",
    188 				      (otmp == uarmg) ? "gloves" :
    189 				      (otmp == uarmh) ? "helmet" : "armor");
    190 				named++;
    191 				(void) armoroff(otmp);
    192 				otmp->cursed = curssv;
    193 				if (multi < 0) {
    194 					/*
    195 					multi = 0;
    196 					nomovemsg = 0;
    197 					afternmv = 0;
    198 					*/
    199 					stealoid = otmp->o_id;
    200 					stealmid = mtmp->m_id;
    201 					afternmv = stealarm;
    202 					return (0);
    203 				}
    204 				break;
    205 			}
    206 		default:
    207 			impossible("Tried to steal a strange worn thing.");
    208 		}
    209 	} else if (otmp == uwep)
    210 		setuwep((struct obj *) 0);
    211 	if (otmp->olet == CHAIN_SYM) {
    212 		impossible("How come you are carrying that chain?");
    213 	}
    214 	if (Punished && otmp == uball) {
    215 		Punished = 0;
    216 		freeobj(uchain);
    217 		free((char *) uchain);
    218 		uchain = (struct obj *) 0;
    219 		uball->spe = 0;
    220 		uball = (struct obj *) 0;	/* superfluous */
    221 	}
    222 	freeinv(otmp);
    223 	pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp));
    224 	mpickobj(mtmp, otmp);
    225 	return ((multi < 0) ? 0 : 1);
    226 }
    227 
    228 void
    229 mpickobj(struct monst *mtmp, struct obj *otmp)
    230 {
    231 	otmp->nobj = mtmp->minvent;
    232 	mtmp->minvent = otmp;
    233 }
    234 
    235 int
    236 stealamulet(struct monst *mtmp)
    237 {
    238 	struct obj     *otmp;
    239 
    240 	for (otmp = invent; otmp; otmp = otmp->nobj) {
    241 		if (otmp->olet == AMULET_SYM) {
    242 			/* might be an imitation one */
    243 			if (otmp == uwep)
    244 				setuwep((struct obj *) 0);
    245 			freeinv(otmp);
    246 			mpickobj(mtmp, otmp);
    247 			pline("%s stole %s!", Monnam(mtmp), doname(otmp));
    248 			return (1);
    249 		}
    250 	}
    251 	return (0);
    252 }
    253 
    254 /* release the objects the killed animal has stolen */
    255 void
    256 relobj(struct monst *mtmp, int show)
    257 {
    258 	struct obj     *otmp, *otmp2;
    259 
    260 	for (otmp = mtmp->minvent; otmp; otmp = otmp2) {
    261 		otmp->ox = mtmp->mx;
    262 		otmp->oy = mtmp->my;
    263 		otmp2 = otmp->nobj;
    264 		otmp->nobj = fobj;
    265 		fobj = otmp;
    266 		stackobj(fobj);
    267 		if (show & cansee(mtmp->mx, mtmp->my))
    268 			atl(otmp->ox, otmp->oy, otmp->olet);
    269 	}
    270 	mtmp->minvent = (struct obj *) 0;
    271 	if (mtmp->mgold || mtmp->data->mlet == 'L') {
    272 		long            tmp;
    273 
    274 		tmp = (mtmp->mgold > 10000) ? 10000 : mtmp->mgold;
    275 		mkgold((long) (tmp + d(dlevel, 30)), mtmp->mx, mtmp->my);
    276 		if (show & cansee(mtmp->mx, mtmp->my))
    277 			atl(mtmp->mx, mtmp->my, '$');
    278 	}
    279 }
    280