Door Smart Mobiles for SmaugWiz
-------------------------------
This code snippet allows mobs of your choosing to know how to use doors as they
wander around. Code is added so that hunting mobiles can use this feature as
well.
This file is best viewed in windows notepad with word wrap turned off.

Terms of Use
------------
You may use this code in any way you wish. hack it
slash it feed it to rabid pirhanas. have fun :D But, if
something breaks it isn't my fault. Any damages, sudden
explosions, etc etc fall entirely in the realm of 
responsibility of you who uses it.

Installation:

1) In Actflags.h in the Mobacts Enum find a free or
   unused position and add ACT_DOORSMART to the list
   of mobile act flags.

2) In the MobActNames add "doorsmart" to the list in the
   same position you added it to the MobActs list.

3) in Update.cpp find the update_mobile function and 
   find the following code segment:
   
			// Wander
			if (! ch->IsAction (ACT_RUNNING)
			  && ! ch->IsAction (ACT_SENTINEL)
			  && ! ch->IsAction (ACT_PROTOTYPE)
			  && (door = number_bits (5)) <= 9
			  && (pexit = get_exit (ch->GetInRoom (), door)) != NULL
			  && pexit->GetToRoom ()
			  && ! pexit->IsClosed ()
			  && ! pexit->GetToRoom ()->IsNoMob ()
			  && ! pexit->GetToRoom ()->IsDeathRoom ()
			  && (! ch->IsAction (ACT_STAY_AREA)
			  || pexit->GetToRoom ()->GetArea () == ch->GetInRoom ()->GetArea ())) {
				retcode = move_char (ch, pexit, 0);

				// If ch changes position due to it's or someother mob's
				// movement via MOBProgs, continue - Kahn
				if (char_died (ch))
					continue;
				if (retcode != rNONE || ch->IsAction (ACT_SENTINEL)
				  || ch->GetPosition () < POS_STANDING)
					continue;
			}
4) Starting here, paste the following code:
			//Mobs that can use doors *maniacal cackle* - Kurgan
			else
			{
				
				CExitData *pfromexit;
				// Added to make mobs know how to work doors
				// the door must be unlocked
				if ( ch->IsAction (ACT_DOORSMART)
				&& ! ch->IsAction (ACT_RUNNING)
				&& ! ch->IsAction (ACT_SENTINEL)
				&& ! ch->IsAction (ACT_PROTOTYPE)
				&& (pexit = get_exit (ch->GetInRoom (), door)) != NULL
				&& pexit->GetToRoom ()
				&& pexit->IsClosed ()
				&& !pexit->IsLocked ()
				&& (! ch->IsAction (ACT_STAY_AREA)
				|| pexit->GetToRoom ()->GetArea () == ch->GetInRoom ()->GetArea ())
				&& ! pexit->IsNoMob ()
				&& ! pexit->GetToRoom ()->IsNoMob ()
				&& ! pexit->GetToRoom ()->IsDeathRoom ())
				{
					do_open(ch, dir_name [pexit->vdir]);
					retcode = move_char (ch, pexit, 0);
					// If ch changes position due to it's or someother mob's
					// movement via MOBProgs, continue - Kahn
					if (char_died (ch))
						continue;
					if (retcode != rNONE || ch->IsAction (ACT_SENTINEL)
					  || ch->GetPosition () < POS_STANDING)
						continue;
					//check the room we moved to for an exit to the room
					//we came from and if there is and it has a door
					//on this side and it's open, close it - Kurgan
					for (pfromexit = ch->GetInRoom ()->first_exit; pfromexit; pfromexit = pfromexit->GetNext ())
					{
						if ((pfromexit = get_exit (ch->GetInRoom (), pfromexit->vdir)) != NULL
						&& pfromexit->GetToRoom ()
						&& (pfromexit->GetToRoom ()->vnum == pexit->rvnum)
						&& pfromexit->IsDoor ()
						&& !pfromexit->IsClosed ())
						{
							do_close(ch, dir_name[pfromexit->vdir]);

						}
					}
				}

			}

	
5) Find the following code segment in the function char_check:

				// running mobs	-Thoric
				if (ch->IsAction (ACT_RUNNING)) {
					if (! ch->IsAction (ACT_SENTINEL)
					  && !ch->GetFightData () && ch->hunting) {
						WAIT_STATE (ch, 2 * PULSE_VIOLENCE);
						hunt_victim (ch);
						continue;
					}

					if (ch->GetSpecialMobFunction ()) {
						if ((*ch->GetSpecialMobFunction ()) (ch))
							continue;
						if (char_died (ch))
							continue;
					}

					if (! ch->IsAction (ACT_SENTINEL)
					  && ! ch->IsAction (ACT_PROTOTYPE)
					  && (door = number_bits (4)) <= 9
					  && (pexit = get_exit (ch->GetInRoom (), door)) != NULL
					  && pexit->GetToRoom ()
					  && ! pexit->IsClosed ()
					  && ! pexit->GetToRoom ()->IsNoMob ()
					  && ! pexit->GetToRoom ()->IsDeathRoom ()
					  && (! ch->IsAction (ACT_STAY_AREA)
					  || pexit->GetToRoom ()->GetArea () == ch->GetInRoom ()->GetArea ())) {
						retcode = move_char (ch, pexit, 0);
						if (char_died (ch))
							continue;
						if (retcode != rNONE || ch->IsAction (ACT_SENTINEL)
						  || ch->GetPosition () < POS_STANDING)
							continue;
					}

6) Starting here paste the following code
					//running doorsmart mobs - Kurgan
					else
					{
						
						CExitData *pfromexit;
						// Added to make mobs know how to work doors
						// the door must be unlocked
						if ( ch->IsAction (ACT_DOORSMART)
						&& ! ch->IsAction (ACT_SENTINEL)
						&& ! ch->IsAction (ACT_PROTOTYPE)
						&& (pexit = get_exit (ch->GetInRoom (), door)) != NULL
						&& pexit->GetToRoom ()
						&& pexit->IsClosed ()
						&& !pexit->IsLocked ()
						&& (! ch->IsAction (ACT_STAY_AREA)
						|| pexit->GetToRoom ()->GetArea () == ch->GetInRoom ()->GetArea ())
						&& ! pexit->IsNoMob ()
						&& ! pexit->GetToRoom ()->IsNoMob ()
						&& ! pexit->GetToRoom ()->IsDeathRoom ())
						{
							do_open(ch, dir_name [pexit->vdir]);
							retcode = move_char (ch, pexit, 0);
							// If ch changes position due to it's or someother mob's
							// movement via MOBProgs, continue - Kahn
							if (char_died (ch))
								continue;
							if (retcode != rNONE || ch->IsAction (ACT_SENTINEL)
							  || ch->GetPosition () < POS_STANDING)
								continue;
							//check the room we moved to for an exit to the room
							//we came from and if there is and it has a door
							//on this side and it's open, close it - Kurgan
							for (pfromexit = ch->GetInRoom ()->first_exit; pfromexit; pfromexit = pfromexit->GetNext ())
							{
								if ((pfromexit = get_exit (ch->GetInRoom (), pfromexit->vdir)) != NULL
								&& pfromexit->GetToRoom ()
								&& (pfromexit->GetToRoom ()->vnum == pexit->rvnum)
								&& pfromexit->IsDoor ()
								&& !pfromexit->IsClosed ())
								{
									do_close(ch, dir_name[pfromexit->vdir]);

								}
							}
						}

					}

7) In Track.cpp find the following code segment in the hunt_victim function:

   ret = find_first_step (ch->GetInRoom (), ch->hunting->who->GetInRoom (), 500 + ch->GetLevel () * 25);
   if (ret<0)
   {
      do_say (ch, "Damn!  Lost my prey!");
      stop_hunting (ch);
      return;
   }
   else
   {
	move_char (ch, get_exit (ch->GetInRoom (), ret), FALSE);

8) Comment out the move_char line above, and paste the following code beneath it:

		CExitData *pfromexit = NULL;
		CExitData *pexit = NULL;
		// Added to make mobs know how to use doors if they have the doorsmart
		// act flag and they are hunting *evil evil grin* - Kurgan
		// the door must be unlocked
		if ( ch->IsAction (ACT_DOORSMART)
		&& ! ch->IsAction (ACT_PROTOTYPE)
		&& (pexit = get_exit (ch->GetInRoom (), ret)) != NULL
		&& pexit->GetToRoom ()
		&& pexit->IsClosed ()
		&& !pexit->IsLocked ()
		&& (! ch->IsAction (ACT_STAY_AREA)
		|| pexit->GetToRoom ()->GetArea () == ch->GetInRoom ()->GetArea ())
		&& ! pexit->IsNoMob ()
		&& ! pexit->GetToRoom ()->IsNoMob ()
		&& ! pexit->GetToRoom ()->IsDeathRoom ())
		{
			do_open(ch, dir_name [pexit->vdir]);
			move_char (ch, pexit, FALSE);
			// If ch changes position due to it's or someother mob's
			// movement via MOBProgs, continue - Kahn
			if (char_died (ch))
				return;
			if (ch->GetPosition () < POS_STANDING)
				return;
			//check the room we moved to for an exit to the room
			//we came from and if there is and it has a door
			//on this side and it's open, close it - Kurgan
			for (pfromexit = ch->GetInRoom ()->first_exit; pfromexit; pfromexit = pfromexit->GetNext ())
			{
				if ((pfromexit = get_exit (ch->GetInRoom (), pfromexit->vdir)) != NULL
				&& pfromexit->GetToRoom ()
				&& (pfromexit->GetToRoom ()->vnum == pexit->rvnum)
				&& pfromexit->IsDoor ()
				&& !pfromexit->IsClosed ())
				{
					do_close(ch, dir_name[pfromexit->vdir]);

				}
			}
		}
		else
		  move_char (ch, get_exit (ch->GetInRoom (), ret), FALSE);

      
9) Now recompile your smaugwiz executable and use mset mob flags doorsmart
   to make the mobile be able to know how to work closed doors.
   NOTE: the code is setup so that nomob flags on exits still apply, the mob
         won't even bother opening the door if it's a nomob exit.

This code was written for SmaugWiz version 2.02. I've installed it following my own
instructions and it works just fine, but I can make no guarantees that it will work 
as is for people who have modified their code a lot. Don't be deterred though, the
code isn't all that difficult and it makes a nice addition.
Imagine you're a character, you're getting beaten up on so you flee, go through a
door, close it and sit down to rest and recuperate...when BAM! in comes the mob
through the door and lays into you again. While that scenario might not be a
player's favorite one...it would get their pulse up a bit :)



Note: This could be made to work on every mobile instead of ones with the
      doorsmart flag if you really want to, but dogs running around opening
      doors just didn't seem right to me...


Happy Hunting :)