Logo Search packages:      
Sourcecode: falconseye version File versions  Download package

mthrowu.c

/*    SCCS Id: @(#)mthrowu.c  3.3   2000/07/07  */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed.  See license for details. */

#include "hack.h"

STATIC_DCL int FDECL(drop_throw,(struct obj *,BOOLEAN_P,int,int));

#define URETREATING(x,y) (distmin(u.ux,u.uy,x,y) > distmin(u.ux0,u.uy0,x,y))

#define POLE_LIM 5      /* How far monsters can use pole-weapons */

#ifndef OVLB

STATIC_DCL const char *breathwep[];

#else /* OVLB */

/*
 * Keep consistent with breath weapons in zap.c, and AD_* in monattk.h.
 */
STATIC_OVL NEARDATA const char *breathwep[] = {
                        "fragments",
                        "fire",
                        "frost",
                        "sleep gas",
                        "a disintegration blast",
                        "lightning",
                        "poison gas",
                        "acid",
                        "strange breath #8",
                        "strange breath #9"
};


int
thitu(tlev, dam, obj, name)   /* u is hit by sth, but not a monster */
int tlev, dam;
struct obj *obj;
const char *name; /* if null, then format `obj' */
{
      const char *onm, *knm;
      boolean is_acid;
      char onmbuf[BUFSZ], knmbuf[BUFSZ];

      if (!name) {
          struct obj otmp;
          unsigned save_ocknown;

          if (!obj) panic("thitu: name & obj both null?");
          name = strcpy(onmbuf, (obj->quan > 1L) ? doname(obj) : xname(obj));
          /* killer name should be more specific; however, exact info
             like blessed/cursed and rustproof make things too verbose */
          otmp = *obj;
          save_ocknown = objects[otmp.otyp].oc_name_known;
          otmp.known = otmp.dknown = 1;
          otmp.bknown = otmp.rknown = otmp.greased = 0;
          /* "killed by poisoned <obj>" would be misleading
             since poison is not the cause of death */
          otmp.opoisoned = 0;
          objects[otmp.otyp].oc_name_known = 1;
          knm = strcpy(knmbuf,
                   (otmp.quan > 1L) ? doname(&otmp) : xname(&otmp));
          objects[otmp.otyp].oc_name_known = save_ocknown;
      } else {
          knm = name;
      }
      onm = (obj && obj_is_pname(obj)) ? the(name) :
                      (obj && obj->quan > 1L) ? name : an(name);
      is_acid = (obj && obj->otyp == ACID_VENOM);

      if(u.uac + tlev <= rnd(20)) {
            if(Blind || !flags.verbose) pline("It misses.");
            else You("are almost hit by %s!", onm);
            return(0);
      } else {
            if(Blind || !flags.verbose) You("are hit!");
            else You("are hit by %s!", onm);

            if (obj && objects[obj->otyp].oc_material == SILVER
                        && hates_silver(youmonst.data)) {
                  dam += rnd(20);
                  pline_The("silver sears your flesh!");
                  exercise(A_CON, FALSE);
            }
            if (is_acid && Acid_resistance)
                  pline("It doesn't seem to hurt you.");
            else {
                  if (is_acid) pline("It burns!");
                  if (Half_physical_damage) dam = (dam+1) / 2;
                  losehp(dam, knm, (obj && obj_is_pname(obj)) ?
                         KILLED_BY : KILLED_BY_AN);
                  exercise(A_STR, FALSE);
            }
            return(1);
      }
}

/* Be sure this corresponds with what happens to player-thrown objects in
 * dothrow.c (for consistency). --KAA
 * Returns 0 if object still exists (not destroyed).
 */

STATIC_OVL int
drop_throw(obj, ohit, x, y)
register struct obj *obj;
boolean ohit;
int x,y;
{
      int retvalu = 1;
      int create;
      struct monst *mtmp;
      struct trap *t;

      if (obj->otyp == CREAM_PIE || obj->oclass == VENOM_CLASS ||
                (ohit && obj->otyp == EGG))
            create = 0;
      else if (ohit && (is_multigen(obj) || obj->otyp == ROCK))
            create = !rn2(3);
      else create = 1;

      if (create && !((mtmp = m_at(x, y)) && (mtmp->mtrapped) &&
                  (t = t_at(x, y)) && ((t->ttyp == PIT) ||
                  (t->ttyp == SPIKED_PIT)))) {
            int objgone = 0;

            if (down_gate(x, y) != -1)
                  objgone = ship_object(obj, x, y, FALSE);
            if (!objgone) {
                  if (!flooreffects(obj,x,y,"fall")) { /* don't double-dip on damage */
                      place_object(obj, x, y);
                      stackobj(obj);
                      retvalu = 0;
                  }
            }
      } else obfree(obj, (struct obj*) 0);
      return retvalu;
}

#endif /* OVLB */
#ifdef OVL1

/* an object launched by someone/thing other than player attacks a monster;
   return 1 if the object has stopped moving (hit or its range used up) */
int
ohitmon(mtmp, otmp, range, verbose)
struct monst *mtmp;     /* accidental target */
struct obj *otmp; /* missile; might be destroyed by drop_throw */
int range;        /* how much farther will object travel if it misses */
                  /* Use -1 to signify to keep going even after hit, */
                  /* unless its gone (used for rolling_boulder_traps) */
boolean verbose;  /* give message(s) even when you can't see what happened */
{
      int damage, tmp;
      boolean vis, ismimic;
      int objgone = 1;

      ismimic = mtmp->m_ap_type && mtmp->m_ap_type != M_AP_MONSTER;
      vis = cansee(bhitpos.x, bhitpos.y);

      tmp = 5 + find_mac(mtmp) + omon_adj(mtmp, otmp, FALSE);
      if (tmp < rnd(20)) {
          if (!ismimic) {
            if (vis) miss(distant_name(otmp, xname), mtmp);
            else if (verbose) pline("It is missed.");
          }
          if (!range) { /* Last position; object drops */
            (void) drop_throw(otmp, 0, mtmp->mx, mtmp->my);
            return 1;
          }
      } else if (otmp->oclass == POTION_CLASS) {
          if (ismimic) seemimic(mtmp);
          mtmp->msleeping = 0;
          if (vis) otmp->dknown = 1;
          potionhit(mtmp, otmp, FALSE);
          return 1;
      } else {
          damage = dmgval(otmp, mtmp);
          if (otmp->otyp == ACID_VENOM && resists_acid(mtmp))
            damage = 0;
          if (ismimic) seemimic(mtmp);
          mtmp->msleeping = 0;
          if (vis) hit(distant_name(otmp,xname), mtmp, exclam(damage));
          else if (verbose) pline("It is hit%s", exclam(damage));

          if (otmp->opoisoned) {
            if (resists_poison(mtmp)) {
                if (vis) pline_The("poison doesn't seem to affect %s.",
                           mon_nam(mtmp));
            } else {
                if (rn2(30)) {
                  damage += rnd(6);
                } else {
                  if (vis) pline_The("poison was deadly...");
                  damage = mtmp->mhp;
                }
            }
          }
          if (objects[otmp->otyp].oc_material == SILVER &&
                hates_silver(mtmp->data)) {
            if (vis) pline_The("silver sears %s flesh!",
                        s_suffix(mon_nam(mtmp)));
            else if (verbose) pline("Its flesh is seared!");
          }
          if (otmp->otyp == ACID_VENOM && cansee(mtmp->mx,mtmp->my)) {
            if (resists_acid(mtmp)) {
                if (vis || verbose)
                  pline("%s is unaffected.", Monnam(mtmp));
                damage = 0;
            } else {
                if (vis) pline_The("acid burns %s!", mon_nam(mtmp));
                else if (verbose) pline("It is burned!");
            }
          }
          mtmp->mhp -= damage;
          if (mtmp->mhp < 1) {
            if (vis || verbose)
                pline("%s is %s!", Monnam(mtmp),
                  (nonliving(mtmp->data) || !vis)
                  ? "destroyed" : "killed");
            mondied(mtmp);
          }

          if (can_blnd((struct monst*)0, mtmp,
                (uchar)(otmp->otyp == BLINDING_VENOM ? AT_SPIT : AT_WEAP),
                otmp)) {
            if (vis && mtmp->mcansee)
                pline("%s is blinded by %s.", Monnam(mtmp), the(xname(otmp)));
            mtmp->mcansee = 0;
            tmp = (int)mtmp->mblinded + rnd(25) + 20;
            if (tmp > 127) tmp = 127;
            mtmp->mblinded = tmp;
          }

          objgone = drop_throw(otmp, 1, bhitpos.x, bhitpos.y);
          if (!objgone && range == -1) {  /* special case */
                obj_extract_self(otmp); /* free it for motion again */
                return 0;
          }
          return 1;
      }
      return 0;
}

void
m_throw(mon, x, y, dx, dy, range, obj)
      register struct monst *mon;
      register int x,y,dx,dy,range;       /* direction and range */
      register struct obj *obj;
{
      register struct monst *mtmp;
      struct obj *singleobj;
      char sym = obj->oclass;
      int hitu, blindinc = 0;

      bhitpos.x = x;
      bhitpos.y = y;

      if (obj->quan == 1L) {
          /*
           * Remove object from minvent.  This cannot be done later on;
           * what if the player dies before then, leaving the monster
           * with 0 daggers?  (This caused the infamous 2^32-1 orcish
           * dagger bug).
           *
           * VENOM is not in minvent - it should already be OBJ_FREE.
           * The extract below does nothing.
           */

          /* not possibly_unwield, which checks the object's */
          /* location, not its existence */
          if (MON_WEP(mon) == obj) {
                obj->owornmask &= ~W_WEP;
                MON_NOWEP(mon);
          }
          obj_extract_self(obj);
          singleobj = obj;
          obj = (struct obj *) 0;
      } else {
          singleobj = splitobj(obj, obj->quan - 1L);
          obj_extract_self(singleobj);
      }

      singleobj->owornmask = 0; /* threw one of multiple weapons in hand? */

      if (singleobj->cursed && (dx || dy) && !rn2(7)) {
          if(canseemon(mon) && flags.verbose) {
            if(is_ammo(singleobj))
                pline("%s misfires!", Monnam(mon));
            else
                pline("%s slips as %s throws it!",
                    The(xname(singleobj)), mon_nam(mon));
          }
          dx = rn2(3)-1;
          dy = rn2(3)-1;
          /* pre-check validity of new direction */
          if((!dx && !dy)
             || !isok(bhitpos.x+dx,bhitpos.y+dy)
             /* missile hits the wall */
             || IS_ROCK(levl[bhitpos.x+dx][bhitpos.y+dy].typ)) {
            (void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
            return;
          }
      }

      /* Note: drop_throw may destroy singleobj.  Since obj must be destroyed
       * early to avoid the dagger bug, anyone who modifies this code should
       * be careful not to use either one after it's been freed.
       */
      if (sym) tmp_at(DISP_FLASH, obj_to_glyph(singleobj));
      while(range-- > 0) { /* Actually the loop is always exited by break */
            bhitpos.x += dx;
            bhitpos.y += dy;
            if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) {
                if (ohitmon(mtmp, singleobj, range, TRUE))
                  break;
            } else if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
                if (multi) nomul(0);

                if (singleobj->oclass == GEM_CLASS &&
                      singleobj->otyp <= LAST_GEM+9 /* 9 glass colors */
                      && is_unicorn(youmonst.data)) {
                  if (singleobj->otyp > LAST_GEM) {
                      You("catch the %s.", xname(singleobj));
                      You("are not interested in %s junk.",
                        s_suffix(mon_nam(mon)));
                      makeknown(singleobj->otyp);
                      dropy(singleobj);
                  } else {
                      You("accept %s gift in the spirit in which it was intended.",
                        s_suffix(mon_nam(mon)));
                      (void)hold_another_object(singleobj,
                        "You catch, but drop, %s.", xname(singleobj),
                        "You catch:");
                  }
                  break;
                }
                if (singleobj->oclass == POTION_CLASS) {
                  if (!Blind) singleobj->dknown = 1;
                  potionhit(&youmonst, singleobj, FALSE);
                  break;
                }
                switch(singleobj->otyp) {
                  int dam, hitv;
                  case EGG:
                      if (!touch_petrifies(&mons[singleobj->corpsenm])) {
                        impossible("monster throwing egg type %d",
                              singleobj->corpsenm);
                        hitu = 0;
                        break;
                      }
                      /* fall through */
                  case CREAM_PIE:
                  case BLINDING_VENOM:
                      hitu = thitu(8, 0, singleobj, (char *)0);
                      break;
                  default:
                      dam = dmgval(singleobj, &youmonst);
                      hitv = 3 - distmin(u.ux,u.uy, mon->mx,mon->my);
                      if (hitv < -4) hitv = -4;
                      if (is_elf(mon->data) &&
                        objects[singleobj->otyp].oc_skill == P_BOW) {
                        hitv++;
                        if (MON_WEP(mon) &&
                            MON_WEP(mon)->otyp == ELVEN_BOW)
                            hitv++;
                        if(singleobj->otyp == ELVEN_ARROW) dam++;
                      }
                      if (bigmonst(youmonst.data)) hitv++;
                      hitv += 8 + singleobj->spe;
                      if (dam < 1) dam = 1;
                      hitu = thitu(hitv, dam, singleobj, (char *)0);
                }
                if (hitu && singleobj->opoisoned) {
                  char onmbuf[BUFSZ], knmbuf[BUFSZ];
                  struct obj otmp;
                  unsigned save_ocknown;

                  /* [see thitu()'s handling of `name'] */
                  Strcpy(onmbuf, xname(singleobj));
                  otmp = *singleobj;
                  save_ocknown = objects[otmp.otyp].oc_name_known;
                  otmp.known = otmp.dknown = 1;
                  otmp.bknown = otmp.rknown = otmp.greased = 0;
                  /* "poisoned by poisoned <obj>" would be redundant */
                  otmp.opoisoned = 0;
                  objects[otmp.otyp].oc_name_known = 1;
                  Strcpy(knmbuf, xname(&otmp));
                  poisoned(onmbuf, A_STR, knmbuf, 10);
                  objects[otmp.otyp].oc_name_known = save_ocknown;
                }
                if(hitu && (singleobj->otyp == CREAM_PIE ||
                         singleobj->otyp == BLINDING_VENOM)) {
                  blindinc = rnd(25);
                  if(singleobj->otyp == CREAM_PIE) {
                      if(!Blind) pline("Yecch!  You've been creamed.");
                      else    pline("There's %s sticky all over your %s.",
                                  something,
                                  body_part(FACE));
                  } else {    /* venom in the eyes */
                      if(ublindf) /* nothing */ ;
                      else if(!Blind) pline_The("venom blinds you.");
                      else Your("%s sting.", makeplural(body_part(EYE)));
                  }
                }
                if (hitu && singleobj->otyp == EGG) {
                  if (!Stone_resistance
                        && !(poly_when_stoned(youmonst.data) &&
                            polymon(PM_STONE_GOLEM)))
                      Stoned = 5;
                      killer = (char *) 0;
                }
                stop_occupation();
                if (hitu || !range) {
                  (void) drop_throw(singleobj, hitu, u.ux, u.uy);
                  break;
                }
            } else if (!range /* reached end of path */
                  /* missile hits edge of screen */
                  || !isok(bhitpos.x+dx,bhitpos.y+dy)
                  /* missile hits the wall */
                  || IS_ROCK(levl[bhitpos.x+dx][bhitpos.y+dy].typ)
#ifdef SINKS
                  /* Thrown objects "sink" */
                  || IS_SINK(levl[bhitpos.x][bhitpos.y].typ)
#endif
                                                ) {
                (void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
                break;
            }
            tmp_at(bhitpos.x, bhitpos.y);
            delay_output();
      }
      tmp_at(bhitpos.x, bhitpos.y);
      delay_output();
      tmp_at(DISP_END, 0);
      /* blindfolds, towels, & lenses keep substances out of your eyes */
      if (blindinc && !ublindf) {
            u.ucreamed += blindinc;
            make_blinded(Blinded + blindinc,FALSE);
      }
}

#endif /* OVL1 */
#ifdef OVLB

/* Remove an item from the monster's inventory and destroy it. */
void
m_useup(mon, obj)
struct monst *mon;
struct obj *obj;
{
      if (obj->quan > 1L) {
            obj->quan--;
      } else {
            obj_extract_self(obj);
            possibly_unwield(mon);
            if (obj->owornmask) {
                mon->misc_worn_check &= ~obj->owornmask;
                update_mon_intrinsics(mon, obj, FALSE);
            }
            dealloc_obj(obj);
      }
}

#endif /* OVLB */
#ifdef OVL1

void
thrwmu(mtmp)      /* monster throws item at you */
register struct monst *mtmp;
{
      struct obj *otmp, *mwep;
      register xchar x, y;
      boolean ispole;
      schar skill;
      int multishot = 1;

      /* Rearranged beginning so monsters can use polearms not in a line */
      if (mtmp->weapon_check == NEED_WEAPON || !MON_WEP(mtmp)) {
          mtmp->weapon_check = NEED_RANGED_WEAPON;
          /* mon_wield_item resets weapon_check as appropriate */
          if(mon_wield_item(mtmp) != 0) return;
      }

      /* Pick a weapon */
      otmp = select_rwep(mtmp);
      if (!otmp) return;
      ispole = is_pole(otmp);
      skill = objects[otmp->otyp].oc_skill;
      mwep = MON_WEP(mtmp);         /* wielded weapon */

      if(ispole || lined_up(mtmp)) {
            /* If you are coming toward the monster, the monster
             * should try to soften you up with missiles.  If you are
             * going away, you are probably hurt or running.  Give
             * chase, but if you are getting too far away, throw.
             */
            x = mtmp->mx;
            y = mtmp->my;
            if(ispole || !URETREATING(x,y) ||
               !rn2(BOLT_LIM-distmin(x,y,mtmp->mux,mtmp->muy)))
            {
                const char *verb = "throws";

                if (otmp->otyp == ARROW
                  || otmp->otyp == ELVEN_ARROW
                  || otmp->otyp == ORCISH_ARROW
                  || otmp->otyp == YA
                  || otmp->otyp == CROSSBOW_BOLT) verb = "shoots";
                if (ispole) {
                  if (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <=
                        POLE_LIM && couldsee(mtmp->mx, mtmp->my))
                      verb = "thrusts";
                  else return; /* Out of range, or intervening wall */
                }

                if (canseemon(mtmp)) {
                  pline("%s %s %s!", Monnam(mtmp), verb,
                        obj_is_pname(otmp) ?
                        the(singular(otmp, xname)) :
                        an(singular(otmp, xname)));
                }

                  /* Use a pole */
                  if (ispole) {
                        int dam = dmgval(otmp, &youmonst);
                        int hitv = 3 - distmin(u.ux,u.uy, mtmp->mx,mtmp->my);

                        if (hitv < -4) hitv = -4;
                        if (bigmonst(youmonst.data)) hitv++;
                        hitv += 8 + otmp->spe;
                        if (dam < 1) dam = 1;
                        (void) thitu(hitv, dam, otmp, (char *)0);

                        return;
                  }

                /* Multishot calculations */
                if ((ammo_and_launcher(otmp, mwep) || skill == P_DAGGER ||
                        skill == -P_DART || skill == -P_SHURIKEN) &&
                      !mtmp->mconf) {
                  /* Assumes lords are skilled, princes are expert */
                  if (is_lord(mtmp->data)) multishot++;
                  if (is_prince(mtmp->data)) multishot += 2;

                  switch (monsndx(mtmp->data)) {
                  case PM_RANGER:
                      multishot++;
                      break;
                  case PM_ROGUE:
                      if (skill == P_DAGGER) multishot++;
                      break;
                  case PM_SAMURAI:
                      if (otmp->otyp == YA && mwep &&
                            mwep->otyp == YUMI) multishot++;
                      break;
                  default:
                      break;
                  }
                  {     /* racial bonus */
                      if (is_elf(mtmp->data) &&
                            otmp->otyp == ELVEN_ARROW &&
                            mwep && mwep->otyp == ELVEN_BOW)
                        multishot++;
                      else if (is_orc(mtmp->data) &&
                            otmp->otyp == ORCISH_ARROW &&
                            mwep && mwep->otyp == ORCISH_BOW)
                        multishot++;
                  }
                }
                if (otmp->quan < multishot) multishot = (int)otmp->quan;
                if (multishot < 1) multishot = 1;
                else multishot = rnd(multishot);
                while (multishot-- > 0)
                  m_throw(mtmp, mtmp->mx, mtmp->my,
                        sgn(tbx), sgn(tby),
                        distmin(mtmp->mx, mtmp->my,
                              mtmp->mux, mtmp->muy),
                        otmp);
                nomul(0);
                return;
            }
      }
}

#endif /* OVL1 */
#ifdef OVLB

int
spitmu(mtmp, mattk)           /* monster spits substance at you */
register struct monst *mtmp;
register struct attack *mattk;
{
      register struct obj *otmp;

      if(mtmp->mcan) {

          if(flags.soundok)
            pline("A dry rattle comes from %s throat.",
                                  s_suffix(mon_nam(mtmp)));
          return 0;
      }
      if(lined_up(mtmp)) {
            switch (mattk->adtyp) {
                case AD_BLND:
                case AD_DRST:
                  otmp = mksobj(BLINDING_VENOM, TRUE, FALSE);
                  break;
                default:
                  impossible("bad attack type in spitmu");
                        /* fall through */
                case AD_ACID:
                  otmp = mksobj(ACID_VENOM, TRUE, FALSE);
                  break;
            }
            if(!rn2(BOLT_LIM-distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy))) {
                if (canseemon(mtmp))
                  pline("%s spits venom!", Monnam(mtmp));
                m_throw(mtmp, mtmp->mx, mtmp->my, sgn(tbx), sgn(tby),
                  distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy), otmp);
                nomul(0);
                return 0;
            }
      }
      return 0;
}

#endif /* OVLB */
#ifdef OVL1

int
breamu(mtmp, mattk)                 /* monster breathes at you (ranged) */
      register struct monst *mtmp;
      register struct attack  *mattk;
{
      /* if new breath types are added, change AD_ACID to max type */
      int typ = (mattk->adtyp == AD_RBRE) ? rnd(AD_ACID) : mattk->adtyp ;

      if(lined_up(mtmp)) {

          if(mtmp->mcan) {
            if(flags.soundok) {
                if(canseemon(mtmp))
                  pline("%s coughs.", Monnam(mtmp));
                else
                  You_hear("a cough.");
            }
            return(0);
          }
          if(!mtmp->mspec_used && rn2(3)) {

            if((typ >= AD_MAGM) && (typ <= AD_ACID)) {

                if(canseemon(mtmp))
                  pline("%s breathes %s!", Monnam(mtmp),
                        breathwep[typ-1]);
                buzz((int) (-20 - (typ-1)), (int)mattk->damn,
                   mtmp->mx, mtmp->my, sgn(tbx), sgn(tby));
                nomul(0);
                /* breath runs out sometimes. Also, give monster some
                 * cunning; don't breath if the player fell asleep.
                 */
                if(!rn2(3))
                  mtmp->mspec_used = 10+rn2(20);
                if(typ == AD_SLEE && !Sleep_resistance)
                  mtmp->mspec_used += rnd(20);
            } else impossible("Breath weapon %d used", typ-1);
          }
      }
      return(1);
}

boolean
linedup(ax, ay, bx, by)
register xchar ax, ay, bx, by;
{
      tbx = ax - bx;    /* These two values are set for use */
      tby = ay - by;    /* after successful return.       */

      /* sometimes displacement makes a monster think that you're at its
         own location; prevent it from throwing and zapping in that case */
      if (!tbx && !tby) return FALSE;

      if((!tbx || !tby || abs(tbx) == abs(tby)) /* straight line or diagonal */
         && distmin(tbx, tby, 0, 0) < BOLT_LIM) {
          if(ax == u.ux && ay == u.uy) return((boolean)(couldsee(bx,by)));
          else if(clear_path(ax,ay,bx,by)) return TRUE;
      }
      return FALSE;
}

boolean
lined_up(mtmp)          /* is mtmp in position to use ranged attack? */
      register struct monst *mtmp;
{
      return(linedup(mtmp->mux,mtmp->muy,mtmp->mx,mtmp->my));
}

#endif /* OVL1 */
#ifdef OVL0

/* Check if a monster is carrying a particular item.
 */
struct obj *
m_carrying(mtmp, type)
struct monst *mtmp;
int type;
{
      register struct obj *otmp;

      for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
            if(otmp->otyp == type)
                  return(otmp);
      return((struct obj *) 0);
}

#endif /* OVL0 */

/*mthrowu.c*/

Generated by  Doxygen 1.6.0   Back to index