Instead of having a bunch of bugfix files for ROM 2.4, what
I'm going to do is just keep one bugfix file. I will append
the bugfixs to this txt file. That way I don't clutter up
my directory with a TON of files. :).

		-Darkoth.

These fixes will apply to ANY version of ROM. It will also
have OLC fixes and etc. 
---------------------------------------------------------------


From: Richard Sanders <belar@whisper.cneti.com>
To: rom@rom.org
Subject: bug fix

This has probably been posted before, but I will do so again to make sure
it is known.

ok the first thing was that I fixed a routine in affect_modify so that it
would properly drop weapons that had gotten too heavy to weild... it is at
the bottom of affect_modify.  The variable 'depth' was never initialized

This made a more subtle bug show up.  In fight.c:  make_corpse, there is a
large for loop that transfers eq from character to corpse.  the skeleton
is as follows: 

OBJ_DATA *obj, *obj_next;

for ( obj = ch->carrying; obj; obj = obj_next )
{
    obj_next = obj->next_content;
    /* code here */
}

this is fine and dandy and as weird as the obj_next looks to me it is
standard for lots of the rom code.  well when I fixed the weild bug, it
made one case of this for loop crash us tho.  When obj is a +str+con eq
and obj_next is the weilded weapon, and the character did not have enough
natural str/con to weild the weapon.  Obj_from_char(obj) indirectly
removed obj_next from the char and dropped it into the room.  this left us
with a reference to an object that we thought was in a char instead of in
the room like it was.  all of the sudden our for loop that should be
iterating the char's inv was iterating the room contents.  We had multiple
calls to obj_to_room on the same object, so a circular link occurred and
caused a loop in show_list_to_char.  A character that made the mistake of
picking up some of this eq just linked his/her inv into the growin list
also.  This is the simple fix: 

for ( obj = ch->carrying; obj; obj = obj->next_content )
{
    /* code here */
}

A simple bug, but so simple that it took almost 3 weeks to find, because I
was not looking for it :)

This default for loop structure is very common in the code and we will be
looking out for possible reoccurances of this type of bug in the future...
it is very easy to get a ref to an obj that is no longer in your list when
so many diff functions are modifying the lists. 

--------
From: dennis@starlifter.reichel.net

Players could previously "break a charm" by using nofollow.
I corrected this in the most simple way possible. (below)

void do_nofollow(CHAR_DATA *ch, char *argument)
{

--  if (IS_NPC(ch))
++  if ( IS_NPC(ch) || IS_AFFECTED( ch, AFF_CHARM ) )
        return;       
 
    if (IS_SET(ch->act,PLR_NOFOLLOW))
    {
      send_to_char("You now accept followers.\n\r",ch);
      REMOVE_BIT(ch->act,PLR_NOFOLLOW);
    }
    else
    {
      send_to_char("You no longer accept followers.\n\r",ch);
      SET_BIT(ch->act,PLR_NOFOLLOW);
      die_follower( ch );
    }
}

Another thing I did, purely a matter of preference, is added to spell_charm:

    if ( victim->position == POS_SLEEPING )
    {
        send_to_char( "You can not get your victim's attention.\n\r", ch );
        send_to_char( "Your slumbers are briefly troubled.\n\r", victim );
        return;
    }

Sleepers are more vulnerable to many forms of attack, but I elected to
make them non-susceptible to charm.

A charmie can't quit now, either, nor can be ordered to post a note or
use the ooc channel.  

Since I test for AFK in is_safe, I make it so a charmie can't set afk.

A proposed rule of thumb: Each player incident that results in code changes
should be balanced by one slaying and corpse eating :-)


Happy Mudding, Dennis

--------
From: Daniel Schumacher <2579@MN.LAWSON.lawson.com>
Subject: Dual Wield and multiple backstabing

Ok here it is,

 For those of you who want to have dual wield but do not want to make the   
thief class unbalanced with the ability to have up to 3 backstabs with   
the first attack. Here is a little positioning within the code.

under:    void multi_hit( CHAR_DATA *ch, CHAR_DATA *victim, int dt )

move the lines: if ( ch->fighting != victim || dt == gsn_backstab )
      return;
and place them between:
  one_hit (ch, victim, dt, FALSE );

place here ------->

  if (get_eq_char (ch, WEAR_SECONDARY) )
  
Take into consideration that I have a class system that is very balanced   
in my opinion. This is one of those FYI's that some people will not like   
but ......that is there opinion. Have fun and I look forward to helping   
more if possible.

  Dan  
--------
in the dual wield patch i have saw that player can dual wield anything
here is a fix on that which i add just put this check statement right
under the function along witht he rest of the check statements:

       if (obj->item_type != ITEM_WEAPON ) {
        send_to_char("You can only weapons.\n\r",ch);
        return;
        }

And also i know of another bug that if a person wield a heavy weapon then
second wield and then remove the heavy weapon and wield anothner weapon
This can bypass light strong weapons.

Here is the fix.  Put this when you are wielding your primary weapon to
check if that person is not wielding a secondary weapon.  If he is then
tell em to remove the second weapon first.

       if ( (get_eq_char( ch, WEAR_SECONDARY ) ) != NULL )
    {
        send_to_char( "Remove your secondary weapon first.\n\r", ch );
        return;
    }

Fixes by Takeda (takeda@mathlab.sunysb.edu)
--------
From: nebby@worldnet.att.net

I just went through this week and fixed all the dual wield problems...
which include:
 * Wielding anything as a second weapon.  If you wield a potion or
something, the values usually correspond to the spell index number of
the potion, which can give you insanely high amounts of damage on the
secondary weapon.
 * Although "second <weapon>" prevents you from carrying a heavy offhand
weapon, if you second, then remove primary, there was no weight
checking.  I changed it to removing primary caused secondary to become
primary.
 * If you are disarmed you keep your secondary in your off hand, and
this is how you want it.
 * I had a function for reincarnates to "create" a powerful weapon in
their primary hand, and it now has weight checking also.
 * Finally, for all the players who complained when the bug was removed,
I added skills for offhand and another skill that would allow you to
wield two equally weighted weapons if you wanted.

-- 
- Nebseni, scribe to the Gods
  Head coder, Clandestine MUD (mud.bcn.net 1234)
--------
Here is a change for Rom 2.4:
** In group_gain of fight.c

add this:
    int highestlevel = 0;

Replace this line:
    lch = (ch->leader != NULL) ? ch->leader : ch;
With this:
    for (lch = ch->in_room->people; lch != NULL; lch = lch->next_in_room)
    {
        if ( !is_same_group( lch, ch ) || IS_NPC(lch))
            continue;

        if (lch->level > highestlevel)
            highestlevel = lch->level;
    }

Then Change the two level checks later to just one check that looks like 
this:
    if ( gch->level - highestlevel <= -5 )
    {
        send_to_char( "Your powers would be useless to such an advanced 
group of adventurers\n\r",ch);
        continue;
    }

In the old code, lch->level was equal to the group leaders level, which
could be a level 1 player.  Then, for example, if a group member(level 50)
killed a some mobile, the level 1 player would gain experience from
it.  This was possible even without the level one landing a single blow.
This new version corrects that.  If you have any remarks about this, 
please let me know.  This is the first time I've posted a coding idea to this 
group =).  And it hasn't been thouroughly tested yet, and I've been known 
to not be accurate in logic ;).

Lotus
lostwaves.op.net 9000
      ______________________________________
      \__________________  _________________\
	__      ______   \ \    __  __  _____
	\ \     \  __ \   \ \   \ \ \ \ \  __\
	 \ \     \ \ \ \   \ \   \ \ \ \ \ \___
	  \ \____ \ \_\ \   \ \   \ \_\ \ \___ \
	   \_____\ \_____\   \_\   \_____\    \ \
	     __________________________________\ \
	     \____________________________________\



--------
From: Oliver Jowett <oliver@sa-search.massey.ac.nz>
Subject: page_to_char patch

This patch modifies page_to_char to concatenate strings sent while another
page_to_char is pending, rather that aborting the first, and also fixes a
memory leak.  This affects (at least) IMC, which calls page_to_char
asynchronously. 

(untested and hand-edited patch follows - sorry 'bout that)

Oliver


--- old-src/comm.c	Thu Mar 20 16:56:28 1997
+++ src/comm.c	Fri Mar 21 12:51:01 1997
@@ -2330,10 +2341,26 @@
 #if defined(macintosh)
 	send_to_char(txt,ch);
 #else
-    ch->desc->showstr_head = alloc_mem(strlen(txt) + 1);
-    strcpy(ch->desc->showstr_head,txt);
-    ch->desc->showstr_point = ch->desc->showstr_head;
-    show_string(ch->desc,"");
+    if (ch->desc->showstr_head &&
+	(strlen(txt)+strlen(ch->desc->showstr_head)+1) < 32000)
+    {
+      char *temp=alloc_mem(strlen(txt) + strlen(ch->desc->showstr_head) + 1);
+      strcpy(temp, ch->desc->showstr_head);
+      strcat(temp, txt);
+      ch->desc->showstr_point = temp + 
+	(ch->desc->showstr_point - ch->desc->showstr_head);
+      free_mem(ch->desc->showstr_head, strlen(ch->desc->showstr_head) + 1);
+      ch->desc->showstr_head=temp;
+    }
+    else
+    {
+      if (ch->desc->showstr_head)
+	free_mem(ch->desc->showstr_head, strlen(ch->desc->showstr_head)+1);
+      ch->desc->showstr_head = alloc_mem(strlen(txt) + 1);
+      strcpy(ch->desc->showstr_head,txt);
+      ch->desc->showstr_point = ch->desc->showstr_head;
+      show_string(ch->desc,"");
+    }
 #endif
 }
 
--------
From: "Ivan Toledo I." <itoledo@ramses.centic.utem.cl>
To: Rom Mailing List <rom@rom.org>
Subject: Pets aren't being extracted

	Just wanted to note that if a player has a pet and gets to the
	password prompt and fails the password check the pet isn't
	extracted from char_list, pet->in_room == NULL... and
	you will probably get segfaults. I made a quick fix
	and I SUPPOSE that this works correctly...( at least i'm
	not getting any bugs now ).

	In close_socket :

	if ( ( ch = dclose->character ) != NULL )
	{
		sprintf( log_buf, "Closing link to %s.", ch->name );
		log_string( log_buf );

		/* add this */
		if ( ch->pet && ch->pet->in_room == NULL )
		{
			char_to_room( ch->pet, get_room_index(ROOM_VNUM_LIMBO) );
			extract_char( ch->pet, TRUE );
		}
		/* stock code continues here */
--------
From: mlkesl <mlkesl@csclub.stthomas.edu>
Subject: romobjl.v1 fix for use with Ivan's OLC

Ok, I think I might have something to contribute once
again to the group, I am glad for all the help I have
got from the group, thanks everyone...

On the subject of Erwin's romobjl.v1,
I asked about it last night then today
put a bunch log_strings into it to see
where it was hanging, as I USED to know
nothing about the OLC code I mindlessly 
copied into the code...

Well, OLC handles resets by room,
rather than by area, or something..
So, SMALL changed have to be made to
Erwin's romobjl.v1 in order for it
to work...

The following is a small section of
Erwin's code for printarea of romobjl.v1
"+++" denotes a line to be added
"---" denotes a line to be commented out

<<<PREVIOUS CODE>>>
void printarea (FILE *fp, AREA_DATA *pArea)
{
        MOB_INDEX_DATA *last_mob; 
        ROOM_INDEX_DATA *last_room;
+++ROOM_INDEX_DATA *pRoom; 
        RESET_DATA * pReset;
        OBJ_RESET *list;
        bool mob_reboot; 
+++int vnum;

        list = new_list ();      
        last_mob = NULL;
        last_room = NULL;
        mob_reboot = FALSE;

        /* run through all the resets in that area*/
---for (pReset = pArea->reset_first; pReset != NULL; pReset = pReset->next)
+++for ( vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++ )
+++if ( ( pRoom = get_room_index(vnum) ) )
+++   for ( pReset = pRoom->reset_first; pReset != NULL; pReset = pReset->next )
<<<REST OF CODE ENSUES>>>

With this addition to the code, it works perfectly for my mud with ivans olc...
I am also the proud new owner of a 381k, 1995 line object dump file :p
Thanks ERWIN!

I hope someone finds this as useful as I have found everyone else's work to be.
Thanks again all :)

Mlkesl
--------
From: sardu@v-wave.com

>I am using Lope's colour code, and very happy with it.
>
>However...
>I want to call the function from the startup (before a character is loaded
>into the game) and the arguments for the function are ( CHAR_DATA *ch,char
>*argument).
>
>Can anyone tell me how to change this so the function is not dependent upon
>character information?  I am trying to dissect the code line-by-line and
>having a bit of difficulty.  Everything seems set on the function SET_BIT
>looking for an act_flag of PLR_COLOUR.  I would like to change this so the
>player need not have that flag, but only needs to say "Yes" upon startup.

Set the bit in the descriptor_data instead of in the char_data and add
another CON state for nanny() that asks the player whether they want colour
or not.


*** in merc.h:

struct descriptor_data
{
    ...
    bool                   colorbit;
};

#define CON_COLOUR_LOGIN     16 /* or whatever is next in your connection
list */


*** in comm.c, in function nanny():

case CON_COLOUR_LOGIN:
    if ( argument[0] == '\0' )
	{
	    close_socket( d );
	    return;
	}

    switch( *argument )
	{
	case 'y' :
	case 'Y' :
		d->colorbit = TRUE;
		d->connected = CON_GET_NAME;
		write_to_buffer( d, "YOUR MUD'S COLOUR ENABLED MESSAGE
HERE.\n\rName: ", 0 );
		return;
	case 'n' :
	case 'N' :
	  	d->colorbit= FALSE;
	  	write_to_buffer( d, "Color off, use the 'colour' command to
enable it.\n\rWhat is your name: ", 0 );
		d->connected = CON_GET_NAME;
		return;
	default:
		write_to_buffer(d,"Please type Y or N:", 0);
		break;
	}
    break;

You will also want to make this new CON state the default. I set it in
recycle.c, if you manage memory from somewhere else, just do it wherever
you init new descriptors.

*** in recycle.c, in new_descriptor()
	DESCRIPTOR_DATA *new_descriptor(void)
	{
	...
	d->connected	= CON_COLOUR_LOGIN;
	...
	}

That's about it, you can either check the descriptor bit for colour, or set
PLR_COLOUR based on the descriptor bit.  If you use the desc bit, make sure
you don't try setting it on mobs (which have no descriptor).  With a
CHAR_DATA, use a check for a descriptor (just see if ch->desc != NULL)
before you check the ch->desc->colorbit.

You'll probably also want to put a "(SOME ANSI IN HERE)\n\r Do you see
color?" message in your greeting message (in ../area/rom.are).

(you'll need to check out http://www.transy.edu/~steven for more info)

--
Sardu
xeomud
telnet://mud.xeo.net:4000
--------
From: Paradise <cmosbob@erols.com>
Subject: found a possible bug...

in the make_corpse function, in fight.c, there may be a bug...

when it puts the money into the corpse, it only checks for gold, not 
silver, so if a mob only has silver, it doesnt get put into the corpse.

to fix this, on our mud, we added this:

"|| ch->silver > 0" into the if check

Paradise
--------
If your getting rid of Midgaard check this out:

From mhaney@earthlink.net Wed Mar 25 17:44:25 1998

Here's some other things I found when starting from scratch:
in db.c,  void load_rooms:  there's a hack to set the whole city of midgaard
to room_law by vnum.  You probably don't need that.

/* horrible hack */
   if ( 3000 <= vnum && vnum < 3400)
    SET_BIT(pRoomIndex->room_flags,ROOM_LAW);

There's also a hack to suppress bad exit errors for the immortal area on
boot-up.  (one-way exits)  Probably, you'll want to just scrap that.  I
added a goofy_exits room flag to put on rooms
with one-way or peculiar exits, and just suppress the errors when that flag
is present.
(I think that stuffs in void_fix_exits.)

Finally, the vnums for guild rooms are coded into the class definitions.
Probably, you want to change those too, so you don't find yourself wandering
around your brand new area, and find a room you're not allowed in.  In
addition to changing those numbers, you might want to change the rountine in
move_char to ignore immortals when checking for class in guild rooms.

Hope that helps, and Hello all, as I'm new to the list.
Just glad I could introduce myself with an answer instead of a question.
Don't expect me to ever be this concise again ;)

Michael Haney  (known as Yukon or Stonefist in various mud-lands)
--------
From meige@ix.netcom.com Fri Mar 27 14:00:05 1998

Dunno if stock ROM is supposed to handle this, but mine wasn't and it
was annoying to see linkdead immortals all over the place and logging
back in without seeing how many new messages I had.

In update.c, in the update_char function, find the line that says
if (IS_IMMORTAL(ch))
and take out the block of code from that until it gets dones with
putting the mortal characters and replace that block you took out with
this:

if (IS_IMMORTAL(ch) && (ch->desc != NULL))
                ch->timer = 0;

            if ( ++ch->timer >= 12 )
            {
                if ( ch->was_in_room == NULL && ch->in_room != NULL )
                {
                    ch->was_in_room = ch->in_room;
                    if ( ch->fighting != NULL )
                        stop_fighting( ch, TRUE );
                    act( "$n disappears into the void.",
                        ch, NULL, NULL, TO_ROOM );
                    send_to_char( "You disappear into the void.\n\r", ch);
                    if (ch->level > 1)
                        save_char_obj( ch );
                    char_from_room( ch );
                    char_to_room( ch, get_room_index( ROOM_VNUM_LIMBO ));
                }
            }

            if ( (ch->desc == NULL) && ( ch->timer >=15 ) ) /* dscnct
after 15 ticks */
            {
              do_quit(ch,"");
               return;
            }

--------
For those with Mobprogs:

From: AMASLIN@aardvark.ucs.ou.edu

This may or may not be the problem, but it's something you might try.  We had a
problem where, when a fido was killed and exploded, it would kill another fido
in the same room and crash.  We fixed it by going into the mobprog code and
making it so that mob damage like that only affects PC's (a simple 
if (!IS_NPC(ch)) should do it).  We haven't had any problems since.


Reorx of Ansalon MUD
ansalon.mudservices.com 8679
--------
From: Hieronymous <hiero@netusa1.net>
Subject: Alloc_mem BUG (Merc Diku 2.2)

Hello, everyone -- 

About a month and a half ago, one of the Implementors on our MUD sent the
following message to this list with questions about the cause of this sort
of bug.  The only suggestion anyone had was that it might have to do with
color code.

Anyway, after a lot of grief, we have puzzled out the cause of this bug and
thought we'd first advise everyone on here in case you have problems with
this at some point and second ask a couple questions as to what might be
the best way to actually go about fixing the problem.

We had started out thinking that perhaps the problem was generated
somewhere in send_to_char or page_to_char, the latter of which I understand
is not in stock Merc Diku 2.2 code.  One thing that troubled us was the
reason that the bug always was for 64000, not for any other number. 
Eventually, we found that checks in send_to_char and page_to_char were not
stopping the bug (which only caused crashes sporadically).  Finally, it
became clear that crashes occurred when a couple characters were attacking
mobs that were self-generating with area effect spells (say, 40+ of those
mobs), particularly those triggered with do_brandish.  An investigation of
do_brandish revealed the use of the act function in comm.c, which in turn
utilized write_to_buffer.  A quick test using those staves on a good-sized
number of guardian vampires (who use the gate spell) corroborated our
suspicions that these battles were causing the problem.  The MUD crashed
with the same bug message after the eighth or ninth brandish.

Now, we are not so confident with write_to_buffer, as we aren't clear on
the purpose of certain of the variables used there (outtop, outsize, etc.).
 Is it possible someone could explain the importance/use of each of the
variables used in write_to_buffer? 

Also, I thought I'd run our temporary bug fix by you folks and see if any
of you have suggestions for improving it or reasons why we should not use
it.

In the final while loop we have the following:

while ( d->outtop + length >= d->outsize )
{
     char *outbuf;

/* new code begins here */
     if ( ( 2 * d->outsize) > 63000 )
     {
        bug("Write_to_buffer:  outsize too large:  %d", d->outsize);
        return;
     }
/* end of new code */

     outbuf   = alloc_mem( 2 * d->outsize );
  etc....

This code *seems* to be working well, except for one problem.  For each
message of damage to the various mobiles, a bug message is generated.  This
means that for every brandish (after the 8th or 9th one), there are 40+ bug
messages, which of course quickly makes for a large log file, at least if
the battle goes on for a while.  Does anyone have a suggestion that could
possibly generate a single bug message?  
Also, is there any reason *not* to fix the problem this way?  Finally, is
there any need to reinitialize d->outsize?  Or is that not necessary?

Ok, I think that is all the questions about this code that we have at this
time.  In advance, thanks for your help, and we hope our experience with
this can help any others of you who have the same problem at some point. 
:)

Hieronymous
NetherWorld
ruby.telmaron.com 3666
http://www.lexiconn.com/users/mud
--------
From: Garry Turkington <G.Turkington@Queens-Belfast.AC.UK>

On Tue, 3 Mar 1998, Realm Of Eternal Darkness MUD wrote:
> There was a hacker on my server tonight.  One that exploits bugs within
> the mud.  Things like that recent discussion of the combine command, if
> you have the outfit command, which most of you do.  Any char under level 6
> can type it over and over, which will give them a shitload of crap in
> their inventory, then if you remove combine and display you inventory, the
> mud is fucked, 

*sigh*, old bannerboy comes out to play again it seems.  This one has been
around for a while.. removing the combine ability is a fix, removing
do_outfit is another.  If you want to keep both, one of the problems is
that do_outfit doesn't check to see if the char can carry the items it
gives them, so it doesnt take a genius to develop a tintin loop to do the
appropriate action.  Even if you check for this though, they still can
abuse it.  A counter limiting the number of times they can do do_outfit is
another possiblity.

>also, try typing buy 99999999999 (item) at a shop where
> item = anything that the shop sells, this will crash it too.  The sockets

It's always a delicate issue talking about crash bugs on an open list,
but since how to do it has been made public, doing the same to the fix
can't hurt any more.  I won't go into why it works though, in case the
principle gives some assholes ideas to try and find others.
This was a new one on me.  Fix for it is in do_buy, where the sanity check
is performed on the numeric argument to ensure no negatives.. since this
was a problem back in B2, I'm not sure if this code is the fix in B3 or my
own..but it will look darn similar.  Currently it's:

if (number < -1)
{
  act("$n tells you 'Get real!'",keeper, NULL, ch, TO_VICT) ;
  return ;
}

Change the condition to something like:

if (count<-1 || count>100)

The 100 is arbitrary, just make it the upper limit of objects you think
anyone will realistically ever buy at one time.

Hope that helps, unfortunately I have a sinking feeling that since this
previous post Rom's all over the place have been cursed with wits trying
this out.

Garry
--------
From: Mull <andersoh@quoin.cqu.edu.au>

Ok, stop me if you've heard this one.

Ever noticed how you can see through closed doors when you scan on a stock
2.4 rom?
Here's a little fix I learned down Mexico way, goes a little like this...

This is found in scan.c; assuming you have one, open it up and look for the
function below.
The lines marked with + are ones I added. If u see/have any problems with
it, or just want to
tell me how much of drongo I am, drop me a line.

void scan_list(ROOM_INDEX_DATA *scan_room, CHAR_DATA *ch, sh_int depth,
sh_int door)
{
   CHAR_DATA *rch;

   if ( scan_room == NULL )
      return;

+/*
+ * this used to cause a mysterious crash here, finally realized it was
+ * 'door' being -1, and rev_dir seems to have a problem with that...
+ * only acted up when it was done in a room with "extra" exits - Mull
+ */
+   if ( door != -1 && scan_room->exit[rev_dir[door]] != NULL
+   && IS_SET(scan_room->exit[rev_dir[door]]->exit_info,EX_CLOSED) )
+      return;

   for (rch=scan_room->people; rch != NULL; rch=rch->next_in_room)
   {
      if (rch == ch)
         continue;
      if (!IS_NPC(rch) && rch->invis_level > get_trust(ch))
         continue;
      if (can_see(ch, rch))
         scan_char(rch, ch, depth, door);
   }
   return;
}

-----------
From: Thunder <thunder1@fast.net>

>   Does anyone out there have any ideas what needs to be changed in
> act()/act_new() to make it accept NPC's?  I have taken out the checks that
> throw out anyone without a ->desc.  But there must be something else I am
> forgetting.  Any thoughts would be greatly appreciated.
> 

Yeah this is an existing bug in the MOBProg snippet.  Here's what you
need to do:

In comm.c find this section of code in function void act_new(): 

              if ((!IS_NPC(to) && to->desc == NULL )
                   || (IS_NPC(to) && !HAS_TRIGGER(to, TRIG_ACT))
                   || to->position < min_pos)
                       continue; 

And replace it with the following:

 	    /*
	     * MOBProgram fix to allow MOBs to see acts()
	     *   -- Thunder (thunder1@fast.net)
	     */
        if ( (to->desc == NULL
        &&    (!IS_NPC(to) || !HAS_TRIGGER(to, TRIG_ACT)))
        ||   to->position < min_pos )
            continue;

That should cure it. :)

--------