diff -urpN src/act_wiz.c new/act_wiz.c
--- src/act_wiz.c	Thu Feb 11 14:39:58 1999
+++ new/act_wiz.c	Sat May 17 19:01:45 2003
@@ -1327,7 +1327,13 @@ void do_ostat( CHAR_DATA *ch, char *argu
 	    send_to_char(buf,ch);
 	    break;
 		
-      
+	case ITEM_BEACON:
+		if(obj->value[1] == 0)
+			strcpy(buf,"It is disabled.\n\r");
+		else
+			sprintf(buf,"It transmits to %s vnum %d.\n\r",
+				obj->value[1] == 1 ? "room" : "object", obj->value[0]);
+		send_to_char(buf, ch);
     	case ITEM_WEAPON:
  	    send_to_char("Weapon type is ",ch);
 	    switch (obj->value[0])
diff -urpN src/bit.c new/bit.c
--- src/bit.c	Sun Feb  7 10:13:50 1999
+++ new/bit.c	Sat May 17 19:01:41 2003
@@ -294,6 +294,7 @@ const struct flag_type type_flags[] =
     {	"clothing",		ITEM_CLOTHING,		TRUE	},
     {	"protect",		ITEM_PROTECT,		TRUE	},
     {	"map",			ITEM_MAP,		TRUE	},
+    {  "beacon",		ITEM_BEACON,		TRUE	},
     {	"",			0,			0	}
 };
 
diff -urpN src/comm.c new/comm.c
--- src/comm.c	Wed Feb  3 17:18:20 1999
+++ new/comm.c	Sat May 17 19:46:02 2003
@@ -2481,22 +2481,114 @@ void fix_sex(CHAR_DATA *ch)
     	ch->sex = IS_NPC(ch) ? 0 : ch->pcdata->true_sex;
 }
 
-void act_new( const char *format, CHAR_DATA *ch, const void *arg1, 
-	      const void *arg2, int type, int min_pos)
+bool send_ok(int type, int min_pos, CHAR_DATA *to, CHAR_DATA *ch, CHAR_DATA *vch)
+{
+	if ( to->desc == NULL || to->position < min_pos )
+		return FALSE;
+	if ( (type == TO_CHAR) && to != ch )
+		return FALSE;
+	if ( type == TO_VICT && ( to != vch || to == ch ) )
+		return FALSE;
+	if ( type == TO_ROOM && to == ch )
+		return FALSE;
+	if ( type == TO_NOTVICT && (to == ch || to == vch) )
+		return FALSE;
+
+	return TRUE;
+}
+
+void write_act(const char *format, CHAR_DATA *to, CHAR_DATA *ch, const void *arg1, const void *arg2)
 {
     static char * const he_she  [] = { "it",  "he",  "she" };
     static char * const him_her [] = { "it",  "him", "her" };
     static char * const his_her [] = { "its", "his", "her" };
- 
-    char buf[MAX_STRING_LENGTH];
-    char fname[MAX_INPUT_LENGTH];
-    CHAR_DATA *to;
     CHAR_DATA *vch = (CHAR_DATA *) arg2;
     OBJ_DATA *obj1 = (OBJ_DATA  *) arg1;
     OBJ_DATA *obj2 = (OBJ_DATA  *) arg2;
+    char buf[MAX_STRING_LENGTH];
+    char fname[MAX_INPUT_LENGTH];
     const char *str;
     const char *i;
     char *point;
+
+	point   = buf;
+	str     = format;
+	while ( *str != '\0' )
+	{
+		if ( *str != '$' )
+		{
+			*point++ = *str++;
+			continue;
+		}
+		++str;
+
+		if ( arg2 == NULL && *str >= 'A' && *str <= 'Z' )
+		{
+			bug( "Act: missing arg2 for code %d.", *str );
+			i = " <@@@> ";
+		}
+		else
+		{
+			switch ( *str )
+			{
+			default:  bug( "Act: bad code %d.", *str );
+					  i = " <@@@> ";                                break;
+			/* Thx alex for 't' idea */
+			case 't': i = (char *) arg1;                            break;
+			case 'T': i = (char *) arg2;                            break;
+			case 'n': i = PERS( ch,  to  );                         break;
+			case 'N': i = PERS( vch, to  );                         break;
+			case 'e': i = he_she  [URANGE(0, ch  ->sex, 2)];        break;
+			case 'E': i = he_she  [URANGE(0, vch ->sex, 2)];        break;
+			case 'm': i = him_her [URANGE(0, ch  ->sex, 2)];        break;
+			case 'M': i = him_her [URANGE(0, vch ->sex, 2)];        break;
+			case 's': i = his_her [URANGE(0, ch  ->sex, 2)];        break;
+			case 'S': i = his_her [URANGE(0, vch ->sex, 2)];        break;
+
+			case 'p':
+				i = can_see_obj( to, obj1 )
+						? obj1->short_descr
+						: "something";
+				break;
+
+			case 'P':
+				i = can_see_obj( to, obj2 )
+						? obj2->short_descr
+						: "something";
+				break;
+
+			case 'd':
+				if ( arg2 == NULL || ((char *) arg2)[0] == '\0' )
+				{
+					i = "door";
+				}
+				else
+				{
+					one_argument( (char *) arg2, fname );
+					i = fname;
+				}
+				break;
+			}
+		}
+
+		++str;
+		while ( ( *point = *i ) != '\0' )
+			++point, ++i;
+	}
+
+	*point++ = '\n';
+	*point++ = '\r';
+	buf[0]   = UPPER(buf[0]);
+	write_to_buffer( to->desc, buf, point - buf );
+}
+
+void act_new( const char *format, CHAR_DATA *ch, const void *arg1, 
+	      const void *arg2, int type, int min_pos)
+{
+	CHAR_DATA *to;
+    CHAR_DATA *vch = (CHAR_DATA *) arg2;
+	OBJ_DATA *obj1, *obj2;
+	ROOM_INDEX_DATA *room;
  
     /*
      * Discard null and zero-length messages.
@@ -2505,10 +2597,10 @@ void act_new( const char *format, CHAR_D
         return;
 
     /* discard null rooms and chars */
-    if (ch == NULL || ch->in_room == NULL)
+    if (ch == NULL || (room = ch->in_room) == NULL)
 	return;
 
-    to = ch->in_room->people;
+    to = room->people;
     if ( type == TO_VICT )
     {
         if ( vch == NULL )
@@ -2517,97 +2609,72 @@ void act_new( const char *format, CHAR_D
             return;
         }
 
-	if (vch->in_room == NULL)
-	    return;
+	if ((room = vch->in_room) == NULL)
+	    return;
 
-        to = vch->in_room->people;
+        to = room->people;
     }
  
     for ( ; to != NULL; to = to->next_in_room )
     {
-        if ( to->desc == NULL || to->position < min_pos )
-            continue;
- 
-        if ( (type == TO_CHAR) && to != ch )
-            continue;
-        if ( type == TO_VICT && ( to != vch || to == ch ) )
-            continue;
-        if ( type == TO_ROOM && to == ch )
-            continue;
-        if ( type == TO_NOTVICT && (to == ch || to == vch) )
-            continue;
- 
-        point   = buf;
-        str     = format;
-        while ( *str != '\0' )
-        {
-            if ( *str != '$' )
-            {
-                *point++ = *str++;
-                continue;
-            }
-            ++str;
- 
-            if ( arg2 == NULL && *str >= 'A' && *str <= 'Z' )
-            {
-                bug( "Act: missing arg2 for code %d.", *str );
-                i = " <@@@> ";
-            }
-            else
-            {
-                switch ( *str )
-                {
-                default:  bug( "Act: bad code %d.", *str );
-                          i = " <@@@> ";                                break;
-                /* Thx alex for 't' idea */
-                case 't': i = (char *) arg1;                            break;
-                case 'T': i = (char *) arg2;                            break;
-                case 'n': i = PERS( ch,  to  );                         break;
-                case 'N': i = PERS( vch, to  );                         break;
-                case 'e': i = he_she  [URANGE(0, ch  ->sex, 2)];        break;
-                case 'E': i = he_she  [URANGE(0, vch ->sex, 2)];        break;
-                case 'm': i = him_her [URANGE(0, ch  ->sex, 2)];        break;
-                case 'M': i = him_her [URANGE(0, vch ->sex, 2)];        break;
-                case 's': i = his_her [URANGE(0, ch  ->sex, 2)];        break;
-                case 'S': i = his_her [URANGE(0, vch ->sex, 2)];        break;
- 
-                case 'p':
-                    i = can_see_obj( to, obj1 )
-                            ? obj1->short_descr
-                            : "something";
-                    break;
- 
-                case 'P':
-                    i = can_see_obj( to, obj2 )
-                            ? obj2->short_descr
-                            : "something";
-                    break;
- 
-                case 'd':
-                    if ( arg2 == NULL || ((char *) arg2)[0] == '\0' )
-                    {
-                        i = "door";
-                    }
-                    else
-                    {
-                        one_argument( (char *) arg2, fname );
-                        i = fname;
-                    }
-                    break;
-                }
-            }
- 
-            ++str;
-            while ( ( *point = *i ) != '\0' )
-                ++point, ++i;
-        }
- 
-        *point++ = '\n';
-        *point++ = '\r';
-        buf[0]   = UPPER(buf[0]);
-        write_to_buffer( to->desc, buf, point - buf );
+
+		if(!send_ok(type, min_pos, to, ch, vch))
+			continue;
+
+		write_act(format, to, ch, arg1, arg2);
     }
- 
+
+	/* check for  beacons */
+	for(obj1 = room->contents; obj1; obj1 = obj1->next_content)
+	{
+		if(obj1->item_type == ITEM_BEACON && obj1->value[0] > 0
+			&& obj1->value[1] > 0)
+		{
+			CHAR_DATA *bch;
+
+			if(obj1->value[1] == 1)
+			{
+				ROOM_INDEX_DATA *bRoom = get_room_index(obj1->value[0]);
+				if(bRoom != NULL)
+				{
+					for(bch = bRoom->people; bch; bch = bch->next_in_room)
+					{
+						if(!send_ok(type, min_pos, bch, ch, vch))
+							continue;
+
+						send_to_char("....", bch);
+						write_act(format, bch, ch, arg1, arg2);
+					}
+				}
+				else
+					obj1->value[0] = 0;
+			}
+			else if(obj1->value[1] >= 2)
+			{
+				DESCRIPTOR_DATA *d;
+
+				for(d = descriptor_list; d; d = d->next)
+				{
+					if((bch = d->character) == NULL)
+						continue;
+
+					if(!send_ok(type, min_pos, bch, ch, vch))
+						continue;
+
+					for(obj2 = vch->carrying; obj2; obj2 = obj2->next_content)
+						if(obj2->pIndexData->vnum == obj1->value[0])
+							break;
+
+					if(!obj2)
+						continue;
+
+					write_act("A strange light emits from $p, you sense a presence...", 
+						bch, ch, obj2, arg2);
+					write_act(format, bch, ch, arg1, arg2);
+				}
+			}
+		}
+	} 
     return;
 }
 
diff -urpN src/const.c new/const.c
--- src/const.c	Sat Feb  6 15:37:06 1999
+++ new/const.c	Sat May 17 19:01:33 2003
@@ -69,6 +69,7 @@ const struct item_type		item_table	[]	=
     {	ITEM_GEM,	"gem"		},
     {	ITEM_JEWELRY,	"jewelry"	},
     {   ITEM_JUKEBOX,	"jukebox"	},
+    {   ITEM_BEACON,   "beacon"	},
     {   0,		NULL		}
 };
 
diff -urpN src/db.c new/db.c
--- src/db.c	Thu Feb 11 14:31:29 1999
+++ new/db.c	Sat May 17 19:48:56 2003
@@ -1621,6 +1621,7 @@ OBJ_DATA *create_object( OBJ_INDEX_DATA 
     case ITEM_ROOM_KEY:
     case ITEM_GEM:
     case ITEM_JEWELRY:
+    case ITEM_BEACON:
 	break;
 
     case ITEM_JUKEBOX:
diff -urpN src/db2.c new/db2.c
--- src/db2.c	Wed Feb 10 15:09:32 1999
+++ new/db2.c	Sat May 17 19:01:46 2003
@@ -414,6 +414,14 @@ void load_objects( FILE *fp )
 	    pObjIndex->value[3]		= fread_number(fp);
 	    pObjIndex->value[4]		= fread_number(fp);
 	    break;
+    case ITEM_BEACON:
+		pObjIndex->value[0]		= fread_number(fp);
+		pObjIndex->value[1]		= fread_number(fp);
+		pObjIndex->value[2]		= fread_number(fp);
+		pObjIndex->value[3]		= fread_number(fp);
+		pObjIndex->value[4]		= fread_number(fp);
+		break;
+
         case ITEM_DRINK_CON:
 	case ITEM_FOUNTAIN:
             pObjIndex->value[0]         = fread_number(fp);
@@ -742,6 +750,7 @@ void convert_object( OBJ_INDEX_DATA *pOb
         case ITEM_MAP:
         case ITEM_CLOTHING:
         case ITEM_SCROLL:
+	 case ITEM_BEACON:
 	    break;
 
         case ITEM_WAND:
diff -urpN src/merc.h new/merc.h
--- src/merc.h	Sun Feb  7 10:26:34 1999
+++ new/merc.h	Sat May 17 19:01:30 2003
@@ -919,6 +919,7 @@ struct	kill_data
 #define ITEM_GEM		     32
 #define ITEM_JEWELRY		     33
 #define ITEM_JUKEBOX		     34
+#define ITEM_BEACON		     35
 
 /*
  * Material types
diff -urpN src/olc_act.c new/olc_act.c
--- src/olc_act.c	Mon Feb  8 18:51:15 1999
+++ new/olc_act.c	Sat May 17 19:04:54 2003
@@ -2180,6 +2180,17 @@ void show_obj_values( CHAR_DATA *ch, OBJ
 	    send_to_char( buf, ch );
 	    break;
 
+	case ITEM_BEACON:
+		sprintf( buf,
+		"[v0] Vnum:    [%d]\n\r"
+		"[v1] Pointer: [%d]\n\r"
+		"     0 == off.\n\r"
+		"     1 == room.\n\r"
+		"     2 == object.\n\r",
+			obj->value[0], obj->value[1]);
+		send_to_char(buf, ch);
+		break;
+
 	case ITEM_DRINK_CON:
 	    sprintf( buf,
 	        "[v0] Liquid Total: [%d]\n\r"
@@ -2413,6 +2424,23 @@ bool set_obj_values( CHAR_DATA *ch, OBJ_
 	            break;
 	    }
             break;
+
+	case ITEM_BEACON:
+		switch ( value_num )
+		{
+			default:
+				do_help( ch, "ITEM_BEACON" );
+				return FALSE;
+			case 0:
+				send_to_char( "VNUM SET.\n\r\n\r", ch);
+				pObj->value[0] = atoi( argument );
+				break;
+			case 1:
+				send_to_char( "POINTER SET.\n\r\n\r", ch);
+				pObj->value[1] = atoi( argument );
+				break;
+		}
+		break;
 
 	case ITEM_FOOD:
 	    switch ( value_num )
diff -urpN src/olc_save.c new/olc_save.c
--- src/olc_save.c	Thu Feb 11 14:49:19 1999
+++ new/olc_save.c	Sat May 17 19:01:38 2003
@@ -284,6 +284,11 @@ void save_object( FILE *fp, OBJ_INDEX_DA
 		     : pObjIndex->value[2] );
 	    break;
 
+		case ITEM_BEACON:
+			fprintf(fp, "%d %d 0 0 0\n",
+			pObjIndex->value[0], pObjIndex->value[1]);
+		break;
+
         case ITEM_PILL:
         case ITEM_POTION:
         case ITEM_SCROLL: