Source:NetHack 3.6.0/src/steed.c

From NetHackWiki
(Redirected from Source:Steed.c)
Jump to: navigation, search

Below is the full text to steed.c from the source code of NetHack 3.6.0. To link to a particular line, write [[Source:NetHack 3.6.0/src/steed.c#line123]], for example.

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

Top of file

  1.  /* NetHack 3.6	steed.c	$NHDT-Date: 1445906867 2015/10/27 00:47:47 $  $NHDT-Branch: master $:$NHDT-Revision: 1.47 $ */
  2.  /* Copyright (c) Kevin Hugo, 1998-1999. */
  3.  /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5.  #include "hack.h"
  6.  
  7.  /* Monsters that might be ridden */
  8.  static NEARDATA const char steeds[] = { S_QUADRUPED, S_UNICORN, S_ANGEL,
  9.                                          S_CENTAUR,   S_DRAGON,  S_JABBERWOCK,
  10.                                          '\0' };
  11.  
  12.  STATIC_DCL boolean FDECL(landing_spot, (coord *, int, int));
  13.  STATIC_DCL void FDECL(maybewakesteed, (struct monst *));
  14.  

rider_cant_reach

  1.  /* caller has decided that hero can't reach something while mounted */
  2.  void
  3.  rider_cant_reach()
  4.  {
  5.      You("aren't skilled enough to reach from %s.", y_monnam(u.usteed));
  6.  }
  7.  

Putting the saddle on

  1.  /*** Putting the saddle on ***/
  2.  

can_saddle

  1.  /* Can this monster wear a saddle? */
  2.  boolean
  3.  can_saddle(mtmp)
  4.  struct monst *mtmp;
  5.  {
  6.      struct permonst *ptr = mtmp->data;
  7.  
  8.      return (index(steeds, ptr->mlet) && (ptr->msize >= MZ_MEDIUM)
  9.              && (!humanoid(ptr) || ptr->mlet == S_CENTAUR) && !amorphous(ptr)
  10.              && !noncorporeal(ptr) && !is_whirly(ptr) && !unsolid(ptr));
  11.  }
  12.  

use_saddle

  1.  int
  2.  use_saddle(otmp)
  3.  struct obj *otmp;
  4.  {
  5.      struct monst *mtmp;
  6.      struct permonst *ptr;
  7.      int chance;
  8.      const char *s;
  9.  
  10.      if (!u_handsy())
  11.          return 0;
  12.  
  13.      /* Select an animal */
  14.      if (u.uswallow || Underwater || !getdir((char *) 0)) {
  15.          pline1(Never_mind);
  16.          return 0;
  17.      }
  18.      if (!u.dx && !u.dy) {
  19.          pline("Saddle yourself?  Very funny...");
  20.          return 0;
  21.      }
  22.      if (!isok(u.ux + u.dx, u.uy + u.dy)
  23.          || !(mtmp = m_at(u.ux + u.dx, u.uy + u.dy)) || !canspotmon(mtmp)) {
  24.          pline("I see nobody there.");
  25.          return 1;
  26.      }
  27.  
  28.      /* Is this a valid monster? */
  29.      if (mtmp->misc_worn_check & W_SADDLE || which_armor(mtmp, W_SADDLE)) {
  30.          pline("%s doesn't need another one.", Monnam(mtmp));
  31.          return 1;
  32.      }
  33.      ptr = mtmp->data;
  34.      if (touch_petrifies(ptr) && !uarmg && !Stone_resistance) {
  35.          char kbuf[BUFSZ];
  36.  
  37.          You("touch %s.", mon_nam(mtmp));
  38.          if (!(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) {
  39.              Sprintf(kbuf, "attempting to saddle %s", an(mtmp->data->mname));
  40.              instapetrify(kbuf);
  41.          }
  42.      }
  43.      if (ptr == &mons[PM_INCUBUS] || ptr == &mons[PM_SUCCUBUS]) {
  44.          pline("Shame on you!");
  45.          exercise(A_WIS, FALSE);
  46.          return 1;
  47.      }
  48.      if (mtmp->isminion || mtmp->isshk || mtmp->ispriest || mtmp->isgd
  49.          || mtmp->iswiz) {
  50.          pline("I think %s would mind.", mon_nam(mtmp));
  51.          return 1;
  52.      }
  53.      if (!can_saddle(mtmp)) {
  54.          You_cant("saddle such a creature.");
  55.          return 1;
  56.      }
  57.  
  58.      /* Calculate your chance */
  59.      chance = ACURR(A_DEX) + ACURR(A_CHA) / 2 + 2 * mtmp->mtame;
  60.      chance += u.ulevel * (mtmp->mtame ? 20 : 5);
  61.      if (!mtmp->mtame)
  62.          chance -= 10 * mtmp->m_lev;
  63.      if (Role_if(PM_KNIGHT))
  64.          chance += 20;
  65.      switch (P_SKILL(P_RIDING)) {
  66.      case P_ISRESTRICTED:
  67.      case P_UNSKILLED:
  68.      default:
  69.          chance -= 20;
  70.          break;
  71.      case P_BASIC:
  72.          break;
  73.      case P_SKILLED:
  74.          chance += 15;
  75.          break;
  76.      case P_EXPERT:
  77.          chance += 30;
  78.          break;
  79.      }
  80.      if (Confusion || Fumbling || Glib)
  81.          chance -= 20;
  82.      else if (uarmg && (s = OBJ_DESCR(objects[uarmg->otyp])) != (char *) 0
  83.               && !strncmp(s, "riding ", 7))
  84.          /* Bonus for wearing "riding" (but not fumbling) gloves */
  85.          chance += 10;
  86.      else if (uarmf && (s = OBJ_DESCR(objects[uarmf->otyp])) != (char *) 0
  87.               && !strncmp(s, "riding ", 7))
  88.          /* ... or for "riding boots" */
  89.          chance += 10;
  90.      if (otmp->cursed)
  91.          chance -= 50;
  92.  
  93.      /* [intended] steed becomes alert if possible */
  94.      maybewakesteed(mtmp);
  95.  
  96.      /* Make the attempt */
  97.      if (rn2(100) < chance) {
  98.          You("put the saddle on %s.", mon_nam(mtmp));
  99.          if (otmp->owornmask)
  100.              remove_worn_item(otmp, FALSE);
  101.          freeinv(otmp);
  102.          /* mpickobj may free otmp it if merges, but we have already
  103.             checked for a saddle above, so no merger should happen */
  104.          (void) mpickobj(mtmp, otmp);
  105.          mtmp->misc_worn_check |= W_SADDLE;
  106.          otmp->owornmask = W_SADDLE;
  107.          otmp->leashmon = mtmp->m_id;
  108.          update_mon_intrinsics(mtmp, otmp, TRUE, FALSE);
  109.      } else
  110.          pline("%s resists!", Monnam(mtmp));
  111.      return 1;
  112.  }
  113.  

Riding the monster

  1.  /*** Riding the monster ***/
  2.  

can_ride

  1.  /* Can we ride this monster?  Caller should also check can_saddle() */
  2.  boolean
  3.  can_ride(mtmp)
  4.  struct monst *mtmp;
  5.  {
  6.      return (mtmp->mtame && humanoid(youmonst.data)
  7.              && !verysmall(youmonst.data) && !bigmonst(youmonst.data)
  8.              && (!Underwater || is_swimmer(mtmp->data)));
  9.  }
  10.  

doride

  1.  int
  2.  doride()
  3.  {
  4.      boolean forcemount = FALSE;
  5.  
  6.      if (u.usteed) {
  7.          dismount_steed(DISMOUNT_BYCHOICE);
  8.      } else if (getdir((char *) 0) && isok(u.ux + u.dx, u.uy + u.dy)) {
  9.          if (wizard && yn("Force the mount to succeed?") == 'y')
  10.              forcemount = TRUE;
  11.          return (mount_steed(m_at(u.ux + u.dx, u.uy + u.dy), forcemount));
  12.      } else {
  13.          return 0;
  14.      }
  15.      return 1;
  16.  }
  17.  

mount_steed

  1.  /* Start riding, with the given monster */
  2.  boolean
  3.  mount_steed(mtmp, force)
  4.  struct monst *mtmp; /* The animal */
  5.  boolean force;      /* Quietly force this animal */
  6.  {
  7.      struct obj *otmp;
  8.      char buf[BUFSZ];
  9.      struct permonst *ptr;
  10.  
  11.      /* Sanity checks */
  12.      if (u.usteed) {
  13.          You("are already riding %s.", mon_nam(u.usteed));
  14.          return (FALSE);
  15.      }
  16.  
  17.      /* Is the player in the right form? */
  18.      if (Hallucination && !force) {
  19.          pline("Maybe you should find a designated driver.");
  20.          return (FALSE);
  21.      }
  22.      /* While riding Wounded_legs refers to the steed's,
  23.       * not the hero's legs.
  24.       * That opens up a potential abuse where the player
  25.       * can mount a steed, then dismount immediately to
  26.       * heal leg damage, because leg damage is always
  27.       * healed upon dismount (Wounded_legs context switch).
  28.       * By preventing a hero with Wounded_legs from
  29.       * mounting a steed, the potential for abuse is
  30.       * reduced.  However, dismounting still immediately
  31.       * heals the steed's wounded legs.  [In 3.4.3 and
  32.       * earlier, that unintentionally made the hero's
  33.       * temporary 1 point Dex loss become permanent.]
  34.       */
  35.      if (Wounded_legs) {
  36.          Your("%s are in no shape for riding.", makeplural(body_part(LEG)));
  37.          if (force && wizard && yn("Heal your legs?") == 'y')
  38.              HWounded_legs = EWounded_legs = 0;
  39.          else
  40.              return (FALSE);
  41.      }
  42.  
  43.      if (Upolyd && (!humanoid(youmonst.data) || verysmall(youmonst.data)
  44.                     || bigmonst(youmonst.data) || slithy(youmonst.data))) {
  45.          You("won't fit on a saddle.");
  46.          return (FALSE);
  47.      }
  48.      if (!force && (near_capacity() > SLT_ENCUMBER)) {
  49.          You_cant("do that while carrying so much stuff.");
  50.          return (FALSE);
  51.      }
  52.  
  53.      /* Can the player reach and see the monster? */
  54.      if (!mtmp || (!force && ((Blind && !Blind_telepat) || mtmp->mundetected
  55.                               || mtmp->m_ap_type == M_AP_FURNITURE
  56.                               || mtmp->m_ap_type == M_AP_OBJECT))) {
  57.          pline("I see nobody there.");
  58.          return (FALSE);
  59.      }
  60.      if (u.uswallow || u.ustuck || u.utrap || Punished
  61.          || !test_move(u.ux, u.uy, mtmp->mx - u.ux, mtmp->my - u.uy,
  62.                        TEST_MOVE)) {
  63.          if (Punished || !(u.uswallow || u.ustuck || u.utrap))
  64.              You("are unable to swing your %s over.", body_part(LEG));
  65.          else
  66.              You("are stuck here for now.");
  67.          return (FALSE);
  68.      }
  69.  
  70.      /* Is this a valid monster? */
  71.      otmp = which_armor(mtmp, W_SADDLE);
  72.      if (!otmp) {
  73.          pline("%s is not saddled.", Monnam(mtmp));
  74.          return (FALSE);
  75.      }
  76.      ptr = mtmp->data;
  77.      if (touch_petrifies(ptr) && !Stone_resistance) {
  78.          char kbuf[BUFSZ];
  79.  
  80.          You("touch %s.", mon_nam(mtmp));
  81.          Sprintf(kbuf, "attempting to ride %s", an(mtmp->data->mname));
  82.          instapetrify(kbuf);
  83.      }
  84.      if (!mtmp->mtame || mtmp->isminion) {
  85.          pline("I think %s would mind.", mon_nam(mtmp));
  86.          return (FALSE);
  87.      }
  88.      if (mtmp->mtrapped) {
  89.          struct trap *t = t_at(mtmp->mx, mtmp->my);
  90.  
  91.          You_cant("mount %s while %s's trapped in %s.", mon_nam(mtmp),
  92.                   mhe(mtmp), an(defsyms[trap_to_defsym(t->ttyp)].explanation));
  93.          return (FALSE);
  94.      }
  95.  
  96.      if (!force && !Role_if(PM_KNIGHT) && !(--mtmp->mtame)) {
  97.          /* no longer tame */
  98.          newsym(mtmp->mx, mtmp->my);
  99.          pline("%s resists%s!", Monnam(mtmp),
  100.                mtmp->mleashed ? " and its leash comes off" : "");
  101.          if (mtmp->mleashed)
  102.              m_unleash(mtmp, FALSE);
  103.          return (FALSE);
  104.      }
  105.      if (!force && Underwater && !is_swimmer(ptr)) {
  106.          You_cant("ride that creature while under water.");
  107.          return (FALSE);
  108.      }
  109.      if (!can_saddle(mtmp) || !can_ride(mtmp)) {
  110.          You_cant("ride such a creature.");
  111.          return (0);
  112.      }
  113.  
  114.      /* Is the player impaired? */
  115.      if (!force && !is_floater(ptr) && !is_flyer(ptr) && Levitation
  116.          && !Lev_at_will) {
  117.          You("cannot reach %s.", mon_nam(mtmp));
  118.          return (FALSE);
  119.      }
  120.      if (!force && uarm && is_metallic(uarm) && greatest_erosion(uarm)) {
  121.          Your("%s armor is too stiff to be able to mount %s.",
  122.               uarm->oeroded ? "rusty" : "corroded", mon_nam(mtmp));
  123.          return (FALSE);
  124.      }
  125.      if (!force
  126.          && (Confusion || Fumbling || Glib || Wounded_legs || otmp->cursed
  127.              || (u.ulevel + mtmp->mtame < rnd(MAXULEV / 2 + 5)))) {
  128.          if (Levitation) {
  129.              pline("%s slips away from you.", Monnam(mtmp));
  130.              return FALSE;
  131.          }
  132.          You("slip while trying to get on %s.", mon_nam(mtmp));
  133.  
  134.          Sprintf(buf, "slipped while mounting %s",
  135.                  /* "a saddled mumak" or "a saddled pony called Dobbin" */
  136.                  x_monnam(mtmp, ARTICLE_A, (char *) 0,
  137.                           SUPPRESS_IT | SUPPRESS_INVISIBLE
  138.                               | SUPPRESS_HALLUCINATION,
  139.                           TRUE));
  140.          losehp(Maybe_Half_Phys(rn1(5, 10)), buf, NO_KILLER_PREFIX);
  141.          return (FALSE);
  142.      }
  143.  
  144.      /* Success */
  145.      maybewakesteed(mtmp);
  146.      if (!force) {
  147.          if (Levitation && !is_floater(ptr) && !is_flyer(ptr))
  148.              /* Must have Lev_at_will at this point */
  149.              pline("%s magically floats up!", Monnam(mtmp));
  150.          You("mount %s.", mon_nam(mtmp));
  151.      }
  152.      /* setuwep handles polearms differently when you're mounted */
  153.      if (uwep && is_pole(uwep))
  154.          unweapon = FALSE;
  155.      u.usteed = mtmp;
  156.      remove_monster(mtmp->mx, mtmp->my);
  157.      teleds(mtmp->mx, mtmp->my, TRUE);
  158.      return (TRUE);
  159.  }
  160.  

exercise_steed

  1.  /* You and your steed have moved */
  2.  void
  3.  exercise_steed()
  4.  {
  5.      if (!u.usteed)
  6.          return;
  7.  
  8.      /* It takes many turns of riding to exercise skill */
  9.      if (u.urideturns++ >= 100) {
  10.          u.urideturns = 0;
  11.          use_skill(P_RIDING, 1);
  12.      }
  13.      return;
  14.  }
  15.  

kick_steed

  1.  /* The player kicks or whips the steed */
  2.  void
  3.  kick_steed()
  4.  {
  5.      char He[4];
  6.      if (!u.usteed)
  7.          return;
  8.  
  9.      /* [ALI] Various effects of kicking sleeping/paralyzed steeds */
  10.      if (u.usteed->msleeping || !u.usteed->mcanmove) {
  11.          /* We assume a message has just been output of the form
  12.           * "You kick <steed>."
  13.           */
  14.          Strcpy(He, mhe(u.usteed));
  15.          *He = highc(*He);
  16.          if ((u.usteed->mcanmove || u.usteed->mfrozen) && !rn2(2)) {
  17.              if (u.usteed->mcanmove)
  18.                  u.usteed->msleeping = 0;
  19.              else if (u.usteed->mfrozen > 2)
  20.                  u.usteed->mfrozen -= 2;
  21.              else {
  22.                  u.usteed->mfrozen = 0;
  23.                  u.usteed->mcanmove = 1;
  24.              }
  25.              if (u.usteed->msleeping || !u.usteed->mcanmove)
  26.                  pline("%s stirs.", He);
  27.              else
  28.                  pline("%s rouses %sself!", He, mhim(u.usteed));
  29.          } else
  30.              pline("%s does not respond.", He);
  31.          return;
  32.      }
  33.  
  34.      /* Make the steed less tame and check if it resists */
  35.      if (u.usteed->mtame)
  36.          u.usteed->mtame--;
  37.      if (!u.usteed->mtame && u.usteed->mleashed)
  38.          m_unleash(u.usteed, TRUE);
  39.      if (!u.usteed->mtame
  40.          || (u.ulevel + u.usteed->mtame < rnd(MAXULEV / 2 + 5))) {
  41.          newsym(u.usteed->mx, u.usteed->my);
  42.          dismount_steed(DISMOUNT_THROWN);
  43.          return;
  44.      }
  45.  
  46.      pline("%s gallops!", Monnam(u.usteed));
  47.      u.ugallop += rn1(20, 30);
  48.      return;
  49.  }
  50.  

landing_spot

  1.  /*
  2.   * Try to find a dismount point adjacent to the steed's location.
  3.   * If all else fails, try enexto().  Use enexto() as a last resort because
  4.   * enexto() chooses its point randomly, possibly even outside the
  5.   * room's walls, which is not what we want.
  6.   * Adapted from mail daemon code.
  7.   */
  8.  STATIC_OVL boolean
  9.  landing_spot(spot, reason, forceit)
  10.  coord *spot; /* landing position (we fill it in) */
  11.  int reason;
  12.  int forceit;
  13.  {
  14.      int i = 0, x, y, distance, min_distance = -1;
  15.      boolean found = FALSE;
  16.      struct trap *t;
  17.  
  18.      /* avoid known traps (i == 0) and boulders, but allow them as a backup */
  19.      if (reason != DISMOUNT_BYCHOICE || Stunned || Confusion || Fumbling)
  20.          i = 1;
  21.      for (; !found && i < 2; ++i) {
  22.          for (x = u.ux - 1; x <= u.ux + 1; x++)
  23.              for (y = u.uy - 1; y <= u.uy + 1; y++) {
  24.                  if (!isok(x, y) || (x == u.ux && y == u.uy))
  25.                      continue;
  26.  
  27.                  if (accessible(x, y) && !MON_AT(x, y)) {
  28.                      distance = distu(x, y);
  29.                      if (min_distance < 0 || distance < min_distance
  30.                          || (distance == min_distance && rn2(2))) {
  31.                          if (i > 0 || (((t = t_at(x, y)) == 0 || !t->tseen)
  32.                                        && (!sobj_at(BOULDER, x, y)
  33.                                            || throws_rocks(youmonst.data)))) {
  34.                              spot->x = x;
  35.                              spot->y = y;
  36.                              min_distance = distance;
  37.                              found = TRUE;
  38.                          }
  39.                      }
  40.                  }
  41.              }
  42.      }
  43.  
  44.      /* If we didn't find a good spot and forceit is on, try enexto(). */
  45.      if (forceit && min_distance < 0
  46.          && !enexto(spot, u.ux, u.uy, youmonst.data))
  47.          return FALSE;
  48.  
  49.      return found;
  50.  }
  51.  

dismount_steed

  1.  /* Stop riding the current steed */
  2.  void
  3.  dismount_steed(reason)
  4.  int reason; /* Player was thrown off etc. */
  5.  {
  6.      struct monst *mtmp;
  7.      struct obj *otmp;
  8.      coord cc;
  9.      const char *verb = "fall";
  10.      boolean repair_leg_damage = (Wounded_legs != 0L);
  11.      unsigned save_utrap = u.utrap;
  12.      boolean have_spot = landing_spot(&cc, reason, 0);
  13.  
  14.      mtmp = u.usteed; /* make a copy of steed pointer */
  15.      /* Sanity check */
  16.      if (!mtmp) /* Just return silently */
  17.          return;
  18.  
  19.      /* Check the reason for dismounting */
  20.      otmp = which_armor(mtmp, W_SADDLE);
  21.      switch (reason) {
  22.      case DISMOUNT_THROWN:
  23.          verb = "are thrown";
  24.      case DISMOUNT_FELL:
  25.          You("%s off of %s!", verb, mon_nam(mtmp));
  26.          if (!have_spot)
  27.              have_spot = landing_spot(&cc, reason, 1);
  28.          losehp(Maybe_Half_Phys(rn1(10, 10)), "riding accident", KILLED_BY_AN);
  29.          set_wounded_legs(BOTH_SIDES, (int) HWounded_legs + rn1(5, 5));
  30.          repair_leg_damage = FALSE;
  31.          break;
  32.      case DISMOUNT_POLY:
  33.          You("can no longer ride %s.", mon_nam(u.usteed));
  34.          if (!have_spot)
  35.              have_spot = landing_spot(&cc, reason, 1);
  36.          break;
  37.      case DISMOUNT_ENGULFED:
  38.          /* caller displays message */
  39.          break;
  40.      case DISMOUNT_BONES:
  41.          /* hero has just died... */
  42.          break;
  43.      case DISMOUNT_GENERIC:
  44.          /* no messages, just make it so */
  45.          break;
  46.      case DISMOUNT_BYCHOICE:
  47.      default:
  48.          if (otmp && otmp->cursed) {
  49.              You("can't.  The saddle %s cursed.",
  50.                  otmp->bknown ? "is" : "seems to be");
  51.              otmp->bknown = TRUE;
  52.              return;
  53.          }
  54.          if (!have_spot) {
  55.              You("can't. There isn't anywhere for you to stand.");
  56.              return;
  57.          }
  58.          if (!has_mname(mtmp)) {
  59.              pline("You've been through the dungeon on %s with no name.",
  60.                    an(mtmp->data->mname));
  61.              if (Hallucination)
  62.                  pline("It felt good to get out of the rain.");
  63.          } else
  64.              You("dismount %s.", mon_nam(mtmp));
  65.      }
  66.      /* While riding, Wounded_legs refers to the steed's legs;
  67.         after dismounting, it reverts to the hero's legs. */
  68.      if (repair_leg_damage) {
  69.          /* [TODO: make heal_legs() take a parameter to handle this] */
  70.          in_steed_dismounting = TRUE;
  71.          heal_legs();
  72.          in_steed_dismounting = FALSE;
  73.      }
  74.  
  75.      /* Release the steed and saddle */
  76.      u.usteed = 0;
  77.      u.ugallop = 0L;
  78.  
  79.      /* Set player and steed's position.  Try moving the player first
  80.         unless we're in the midst of creating a bones file. */
  81.      if (reason == DISMOUNT_BONES) {
  82.          /* move the steed to an adjacent square */
  83.          if (enexto(&cc, u.ux, u.uy, mtmp->data))
  84.              rloc_to(mtmp, cc.x, cc.y);
  85.          else /* evidently no room nearby; move steed elsewhere */
  86.              (void) rloc(mtmp, FALSE);
  87.          return;
  88.      }
  89.      if (mtmp->mhp > 0) {
  90.          place_monster(mtmp, u.ux, u.uy);
  91.          if (!u.uswallow && !u.ustuck && have_spot) {
  92.              struct permonst *mdat = mtmp->data;
  93.  
  94.              /* The steed may drop into water/lava */
  95.              if (!is_flyer(mdat) && !is_floater(mdat) && !is_clinger(mdat)) {
  96.                  if (is_pool(u.ux, u.uy)) {
  97.                      if (!Underwater)
  98.                          pline("%s falls into the %s!", Monnam(mtmp),
  99.                                surface(u.ux, u.uy));
  100.                      if (!is_swimmer(mdat) && !amphibious(mdat)) {
  101.                          killed(mtmp);
  102.                          adjalign(-1);
  103.                      }
  104.                  } else if (is_lava(u.ux, u.uy)) {
  105.                      pline("%s is pulled into the lava!", Monnam(mtmp));
  106.                      if (!likes_lava(mdat)) {
  107.                          killed(mtmp);
  108.                          adjalign(-1);
  109.                      }
  110.                  }
  111.              }
  112.              /* Steed dismounting consists of two steps: being moved to another
  113.               * square, and descending to the floor.  We have functions to do
  114.               * each of these activities, but they're normally called
  115.               * individually and include an attempt to look at or pick up the
  116.               * objects on the floor:
  117.               * teleds() --> spoteffects() --> pickup()
  118.               * float_down() --> pickup()
  119.               * We use this kludge to make sure there is only one such attempt.
  120.               *
  121.               * Clearly this is not the best way to do it.  A full fix would
  122.               * involve having these functions not call pickup() at all,
  123.               * instead
  124.               * calling them first and calling pickup() afterwards.  But it
  125.               * would take a lot of work to keep this change from having any
  126.               * unforeseen side effects (for instance, you would no longer be
  127.               * able to walk onto a square with a hole, and autopickup before
  128.               * falling into the hole).
  129.               */
  130.              /* [ALI] No need to move the player if the steed died. */
  131.              if (mtmp->mhp > 0) {
  132.                  /* Keep steed here, move the player to cc;
  133.                   * teleds() clears u.utrap
  134.                   */
  135.                  in_steed_dismounting = TRUE;
  136.                  teleds(cc.x, cc.y, TRUE);
  137.                  in_steed_dismounting = FALSE;
  138.  
  139.                  /* Put your steed in your trap */
  140.                  if (save_utrap)
  141.                      (void) mintrap(mtmp);
  142.              }
  143.              /* Couldn't... try placing the steed */
  144.          } else if (enexto(&cc, u.ux, u.uy, mtmp->data)) {
  145.              /* Keep player here, move the steed to cc */
  146.              rloc_to(mtmp, cc.x, cc.y);
  147.              /* Player stays put */
  148.              /* Otherwise, kill the steed */
  149.          } else {
  150.              killed(mtmp);
  151.              adjalign(-1);
  152.          }
  153.      }
  154.  
  155.      /* Return the player to the floor */
  156.      if (reason != DISMOUNT_ENGULFED) {
  157.          in_steed_dismounting = TRUE;
  158.          (void) float_down(0L, W_SADDLE);
  159.          in_steed_dismounting = FALSE;
  160.          context.botl = 1;
  161.          (void) encumber_msg();
  162.          vision_full_recalc = 1;
  163.      } else
  164.          context.botl = 1;
  165.      /* polearms behave differently when not mounted */
  166.      if (uwep && is_pole(uwep))
  167.          unweapon = TRUE;
  168.      return;
  169.  }
  170.  

maybewakesteed

  1.  /* when attempting to saddle or mount a sleeping steed, try to wake it up
  2.     (for the saddling case, it won't be u.usteed yet) */
  3.  STATIC_OVL void
  4.  maybewakesteed(steed)
  5.  struct monst *steed;
  6.  {
  7.      int frozen = (int) steed->mfrozen;
  8.      boolean wasimmobile = steed->msleeping || !steed->mcanmove;
  9.  
  10.      steed->msleeping = 0;
  11.      if (frozen) {
  12.          frozen = (frozen + 1) / 2; /* half */
  13.          /* might break out of timed sleep or paralysis */
  14.          if (!rn2(frozen)) {
  15.              steed->mfrozen = 0;
  16.              steed->mcanmove = 1;
  17.          } else {
  18.              /* didn't awake, but remaining duration is halved */
  19.              steed->mfrozen = frozen;
  20.          }
  21.      }
  22.      if (wasimmobile && !steed->msleeping && steed->mcanmove)
  23.          pline("%s wakes up.", Monnam(steed));
  24.      /* regardless of waking, terminate any meal in progress */
  25.      finish_meating(steed);
  26.  }
  27.  

stucksteed

  1.  /* decide whether hero's steed is able to move;
  2.     doesn't check for holding traps--those affect the hero directly */
  3.  boolean
  4.  stucksteed(checkfeeding)
  5.  boolean checkfeeding;
  6.  {
  7.      struct monst *steed = u.usteed;
  8.  
  9.      if (steed) {
  10.          /* check whether steed can move */
  11.          if (steed->msleeping || !steed->mcanmove) {
  12.              pline("%s won't move!", upstart(y_monnam(steed)));
  13.              return TRUE;
  14.          }
  15.          /* optionally check whether steed is in the midst of a meal */
  16.          if (checkfeeding && steed->meating) {
  17.              pline("%s is still eating.", upstart(y_monnam(steed)));
  18.              return TRUE;
  19.          }
  20.      }
  21.      return FALSE;
  22.  }
  23.  

place_monster

  1.  void
  2.  place_monster(mon, x, y)
  3.  struct monst *mon;
  4.  int x, y;
  5.  {
  6.      if (mon == u.usteed
  7.          /* special case is for convoluted vault guard handling */
  8.          || (DEADMONSTER(mon) && !(mon->isgd && x == 0 && y == 0))) {
  9.          impossible("placing %s onto map?",
  10.                     (mon == u.usteed) ? "steed" : "defunct monster");
  11.          return;
  12.      }
  13.      mon->mx = x, mon->my = y;
  14.      level.monsters[x][y] = mon;
  15.  }
  16.  
  17.  /*steed.c*/