pdirt/data/
pdirt/data/HELP/
pdirt/data/HELP/0/
pdirt/data/HELP/F/
pdirt/data/HELP/G/
pdirt/data/HELP/H/
pdirt/data/HELP/J/
pdirt/data/HELP/K/
pdirt/data/HELP/O/
pdirt/data/HELP/Q/
pdirt/data/HELP/R/
pdirt/data/HELP/U/
pdirt/data/HELP/V/
pdirt/data/HELP/Y/
pdirt/data/HELP/Z/
pdirt/data/MESSAGES/
pdirt/data/POWERINFO/
pdirt/data/WIZ_ZONES/
pdirt/drv/
pdirt/drv/bin/
pdirt/drv/compiler/converter/
pdirt/drv/compiler/libs/
pdirt/drv/compiler/scripts/
pdirt/drv/include/AberChat/
pdirt/drv/include/InterMud/
pdirt/drv/include/machine/
pdirt/drv/src/InterMud/
pdirt/drv/src/Players/
pdirt/drv/utils/UAFPort/
pdirt/drv/utils/dnsresolv/
pdirt/drv/utils/gdbm/
#define MOVE_C

/* Heavy revisions done by Marty - Wasteland Project 1996 (ver 1.2.3.x and up)
 * Wasteland is pDirt predecessor
 */
#include <string.h>
#include <strings.h>
#include "kernel.h"
#include "mobile.h"
#include "mflags.h"
#include "move.h"
#include "sendsys.h"
#include "fight.h"
#include "lflags.h"
#include "parse.h"
#include "objsys.h"
#include "bprintf.h"
#include "rooms.h"
#include "mud.h"
#include "uaf.h"
#include "tables.h"
#include "quest.h"
#include "special.h"
#include "zones.h"

static char *exittxt[] =
{
  "north", "east", "south", "west", "up", "down", 
  "northeast", "northwest", "southeast", "southwest",
  "n", "e", "s", "w", "u", "d", "ne", "nw", "se", "sw",
  0
};

static int exitnum[] =
{
  1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
  1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};

void do_follow();

A_COMMAND(dodirn)
/*int dodirn (int vb)*/
{ int vb = verbnumber;
  char block[SETIN_MAX+100];
  int i, pc, n, c,pl;
  int myloc;
  int newch, drnum, droff;
  
  /* Some standard checks for alias sleep etc */
  if (cur_player->polymorphed != -1)
  {  bprintf("I'm sorry, but you can't move while aliased.\n");
     return;
  }
  if (the_world->w_start_loc != 0 && plev(mynum) < LVL_APPREN &&
      ploc(mynum) == the_world->w_start_loc)
  {  bprintf("I'm sorry, but you cannot leave this place at the moment.\n");
     return;
  }
  
  if (pfighting (mynum) >= 0)
  {   bprintf ("You can't just stroll out of a fight!\n"
               "If you wish to leave, you must FLEE in a direction.\n");
      return;
  }

  n = vb - 2;			/* Since VERB_NORTH = 2 etc....stupid */
  
  if (chkcrip () || chksitting ())
    return;
  
  newch = getexit (ploc (mynum), n);

  if (newch >= EX_SPECIAL && newch < EX_MAX)
  {   
/*
int i;
      for (i=0; special_exits[i][0] != -1; i++)
        if (special_exits[i][0] == newch)
        {   int loc = special_exits[i][1];
 */
            if (rom_fun(ploc(mynum)) != NULL)
            {   param_s.loc = newch;
                param_s.ret = 1;
                rom_fun(ploc(mynum))(E_SPECIALEXIT);
                if (param_s.ret != 1)
                   return;
                newch = param_s.loc;
            }
/*
            else
                newch = loc;
            continue;
        }
*/
  } 
  else if (newch >= DOOR && newch < EDOOR)
  {   drnum = newch - DOOR;
      droff = /*drnum ^ 1 */ olinked (drnum);	/* other door side */
	  
      if (state (drnum))
      {  if (!EQ (oname (drnum), "door") || isdark () ||
             EMPTY (olongt (drnum, state (drnum))))
		bprintf ("You can't go that way.\n");
	 else
	     bprintf ("The door is closed.\n");
	 return;
      }
      newch = /*oloc(droff) */ obj_loc (droff);
  }

  if (!exists (newch))
  {  bprintf ("You can't go that way.\n");
     return;
  }
  
  if (!checklevel(mynum, newch)) 
      return;

  if (!has_access_to(mynum,newch,-1))
  {   bprintf("You are forbidden to enter this zone as an immortal.\n");
      return;
  }

  /* Be fair to newbie's */
  if (ltstflg(newch,LFL_DEATH) && plev(mynum) < LVL_FIVE)
  {   bprintf("The gods forgive your stupid move and allow you to live.. for now.\n");
      return;
  }

  /* Special event code */  
  param_s.plx = mynum;
  param_s.pl  = -1;
  param_s.loc = ploc(mynum);
  param_s.ob  = n;         /* Use to give direction */
  param_s.ret = 1;
  param_s.misc = newch;    /* Use to indicate new location */

  /* Check the room for any special events, and if it has one try if
   * It is needed here.
   * Minimum checks: Fail = 1
   *                 Pass = 2
   */  
  if (rom_fun(ploc(mynum)) != NULL)    
  {  rom_fun(ploc(mynum))(E_ONMOVE);
     if (param_s.ret != 1)
       return;
  }

  /* Then try all mobiles in the room for the same thing, see if they are 
   * alive, see if they have something special and then perhaps do it
   * Minimum checks: Fail = lnumchars(ploc(mynum))
   *                 Pass = 4 * lnumchars(ploc(mynum))
   */
  for (c=0; c < lnumchars(ploc(mynum)); c++)
  {  pl = lmob_nr(c,ploc(mynum));
     
     if (alive(pl) == -1)     /* Dead people dont do anything */
       continue;
       
     if (mob_fun(pl) != NULL) 
     {  param_s.pl = pl;
        mob_fun(pl)(E_ONMOVE);
        if (param_s.ret != 1)
          return;
        else newch = param_s.misc;
     }

     /* If No special event, then do a check for a Bar flag, if the player
      * is not a wizard. Also check if the right bar is used.
      */
     if (plev(mynum) < LVL_APPREN)
     {  if (mtstflg(pl,MFL_BLOCK))
        {  bprintf("\001p%s\003 says &+w'Over my dead body!'&*\n",pname(pl));
           setpfighting(pl,mynum);
           return;
        }
        if (mtstflg(pl,MFL_BAR_N) && n == EX_NORTH)
        {  bprintf ("\001p%s\003 says &+w'None shall pass!'&*\n", pname (pl));
           return;
        } else
        if (mtstflg(pl,MFL_BAR_E) && n == EX_EAST)
        {  bprintf ("\001p%s\003 won't let you go East!\n", pname (pl));
           return;
        } else
        if (mtstflg(pl,MFL_BAR_S) && n == EX_SOUTH)
        {  bprintf ("\001p%s\003 holds you back!\n", pname (pl));
           return;
        } else        
        if (mtstflg(pl,MFL_BAR_W) && n == EX_WEST)
        {  bprintf ("\001p%s\003 won't let you go West!\n", pname (pl));
           return;
        } else        
        if (mtstflg(pl,MFL_BAR_U) && n == EX_UP)
        {  bprintf ("\001p%s\003 blocks your way Up!\n", pname (pl));
           return;
        } else     
        if (mtstflg(pl,MFL_BAR_D) && n == EX_DOWN)
        {  bprintf ("\001p%s\003 refuses to let you go Down!\n", pname (pl));
           return;
        }     
     }
  }
  
  /* Then check to see if the next room has something to say about entering
   * the room. If so, use it or otherwise just ignore.
   * Minimum checks: Fail = 1
   *                 Pass = 2
   */
  if (rom_fun(newch) != NULL)
  {  param_s.plx = mynum;
     param_s.ob  = n;
     param_s.misc= newch;
     param_s.ret = 1;
     rom_fun(newch)(E_ONENTRY);
     if (param_s.ret != 1)
       return;
     newch = param_s.misc;
  }     
  /* End to special events */
  
  if (ltstflg (newch, LFL_PRIVATE) || ltstflg (newch, LFL_ONE_PERSON))
  {   pc = 0;
      for (i = 0; i < max_players; i++)
	if (!EMPTY (pname (i)) && ploc (i) == newch && i != mynum)
	  pc++;

      if (pc > (ltstflg (newch, LFL_PRIVATE) ? 1 : 0))
      {
	  bprintf ("I'm sorry, that room is currently full.\n");
          if (cur_player->i_follow != -1)
          {  bprintf("You stop following %s",pname(cur_player->i_follow));
             sendf(cur_player->i_follow,"%s stops following you.\n", pname(mynum));
             cur_player->i_follow = -1;
          }
	  return;
      }
  }

  if ((ltstflg (newch, LFL_ON_WATER) || ltstflg(newch,LFL_RAPIDS)) && 
      plev(mynum) < LVL_APPREN)
  {   Boolean hasboat = carries_boat(mynum);
      Boolean hasraft = carries_raft(mynum);

      if (!hasboat && !hasraft)
      {
	  bprintf ("You need a boat to go onto open water!\n");
	  return;
      }
      else if (ltstflg(newch,LFL_RAPIDS))
      {   if (!hasraft)
          {  if (hasboat)
                 bprintf("Your craft is unsuitable for a river journey such as this.\n");
             else
                 bprintf("You need a raft to travel on this river.\n");
             return;
          }
      }
  }

  if (ltstflg (newch, LFL_IN_WATER))
  { 
      if (plev (mynum) < LVL_APPREN)
      {   int i,total_worn = 0;
 
          for (i=0; amulets[i] != -1; i++)
             if (iswornby(amulets[i],mynum))
                total_worn++;

          if (total_worn <= 0)
	  {
	      bprintf ("You'd surely drown!\n");
	      return;
	  }
	  else
	  {
	      bprintf("You see bubbles rising as you exhale under water.\n");
	  }
      }
  }

  if (mynum < max_players)
  {   
      send_msg (ploc (mynum), 0, pvis (mynum), LVL_MAX,
		mynum, NOBODY, "%s\n",
		build_setin (mynum, block, cur_player->setout, pname (mynum), exittxt[n]));
      send_msg (newch, 0, pvis (mynum), LVL_MAX,
		mynum, NOBODY, "%s\n",
		build_setin (mynum, block, cur_player->setin, pname (mynum), NULL));

      if (pvis(mynum) > 0 && plev(mynum) < LVL_APPREN)
      {	  send_msg (ploc (mynum), MODE_NODEAF, LVL_MIN, pvis(mynum), mynum, NOBODY,
		    "You hear someone moving %swards.\n", exittxt[n]);
	  send_msg (newch, MODE_NODEAF, LVL_MIN, pvis(mynum), mynum, NOBODY,
		    "You hear someone arriving.\n");
      }
  }
  else
  {   if (mynum < max_players && pdrunk(mynum) > 0)
      {   send_msg(ploc(mynum), MODE_NOBLIND, pvis(mynum), LVL_MAX, mynum, NOBODY,
                "%s stumbles %s.\n",pname(mynum), exittxt[n]);
          send_msg(newch, MODE_NOBLIND, pvis(mynum), LVL_MAX, mynum, NOBODY, 
                "%s comes stumbling in.\n", pname(mynum));
      }
      else
      {  send_msg (ploc (mynum), MODE_NOBLIND, pvis (mynum), LVL_MAX, mynum, NOBODY, "%s\n",
		build_setin (mynum, block, cur_player->setout, pname (mynum), exittxt[n]));
      
         send_msg (newch, MODE_NOBLIND, pvis (mynum), LVL_MAX, mynum, NOBODY, "%s\n",
		build_setin (mynum,block, cur_player->setin, pname (mynum), NULL));
      }
  }
  setpfighting (mynum, -1);
  myloc = ploc(mynum);
  trapch(newch);

  if (rom_fun(newch) != NULL)
  {  param_s.plx = mynum;
     param_s.ob  = n;
     param_s.misc= newch;
     param_s.ret = 1;
     rom_fun(newch)(E_AFTERENTRY);
     if (param_s.ret != 1)
       return;
  }     

  do_follow(mynum,vb);
}

void do_follow(int old_mynum,int dir)
{ int i,newch;

  for (i=0; i<max_players; i++)
    if (players[i].iamon && (players[i].i_follow == old_mynum))
    {   if (pfighting(i) >= 0 && !IN_GROUP(i))
        {  sendf(i,"You can not follow %s out of a fight!\n",pname(old_mynum));
           sendf(i,"You no longer follow %s\n",pname(old_mynum));
           sendf(old_mynum,"%s has stopped following you.\n",pname(i));
           players[i].i_follow = -1;
           continue;
        }
        if (ltstflg(ploc(mynum), LFL_ON_WATER) && !carries_boat(i))
        {  sendf(i,"You can not follow %s onto water\n",pname(old_mynum));
           sendf(i,"You stop following %s\n",pname(old_mynum));
           sendf(old_mynum,"%s has stopped following you.\n",pname(i));
           players[i].i_follow = -1;
           continue;
        }
        if (ploc(i) == ploc(old_mynum))
          continue;

        newch = lexit(ploc(i),(dir-2));
	if (newch >= DOOR && newch < EDOOR)
	   newch = oloc(olinked(newch-DOOR));

	if (ploc(old_mynum) != newch)
        {   sendf(i,"You can no longer follow %s.\n",pname(old_mynum));
            sendf(old_mynum,"%s stops following you.\n",pname(i));
            players[i].i_follow = -1;
            continue;
        }

	setup_globals(i);
        verbnumber = dir;
	dodirn();

        if (ploc(i) != ploc(old_mynum))
        {   sendf(i,"You can't follow %s anymore.\n",pname(old_mynum));
            sendf(old_mynum,"%s has stopped following you.\n",pname(i));
            players[i].i_follow = -1;
        }
    }

  setup_globals(old_mynum);
}   

A_COMMAND(dogocom)   
{
  int a = (brkword () == -1) ? get_rand_exit_dir(ploc(mynum)) 
                             : chklist (wordbuf, exittxt, exitnum) - 1;

  if (a < 0 || a >= NEXITS)
    {
      bprintf ("Go where?\n");
      return;
    }
 
 verbnumber = a + 2;
 dodirn ();
}