/*
	This is just a hacked up version of Rom's Portal code without having 
	to use the warp stone. I don't use Rom but I have pretty mud the same 
	setup. Some of the code below for the portal descriptions come from 
	Daleken by Martin Thomson (Symposium). I just replaced the event system
	code with standard Rom/Merc code.

	Chris

	* When a Cleric / Mage casts portal to a mob or player, they see;

		You tear a rift through space and a shimmering portal appears.

	* Then, the portal in the room (do_look) will show the description as;

		A shimmering magical portal to The Main Street is here. (c port fido)

    ** The nexus code found below shows both the to and from rooms it leads to.

 */
 /*
limbo object. (Merc OBJ) You should only need... to %s is here.

#23
portal~
a shimmering portal~
A shimmering magical portal to %s is here.~
~
29 0 0
0~ 0~ 0~ 0~
100 0 0
*/


char *target_name;

void spell_portal (int sn, int level, CHAR_DATA * ch, void *vo, int target)
{
  char buf[MAX_INPUT_LENGTH];
  CHAR_DATA *victim;
  OBJ_DATA *portal;
  ROOM_INDEX_DATA *to_room, *from_room;

  from_room = ch->in_room;

  if ((victim = get_char_world (ch, target_name)) == NULL
      || victim == ch
      || (to_room = victim->in_room) == NULL
      || IS_SET (to_room->room_flags, ROOM_SAFE)
      || IS_SET (to_room->room_flags, ROOM_PRIVATE)
      || IS_SET (to_room->room_flags, ROOM_NO_PORTAL)
      || IS_SET (from_room->room_flags, ROOM_NO_PORTAL)
      || victim->level >= level + 3
      || (!IS_NPC (victim) && victim->level >= LEVEL_HERO)
      || (IS_NPC (victim) && saves_spell (level, victim)))
  {
    send_to_char ("Your spell fizzles.\n\r", ch);
    return;
  }

  portal = create_object (get_obj_index (OBJ_VNUM_PORTAL), 0);
  portal->timer = 1 + level / 10;
  portal->value[3] = to_room->vnum;
  sprintf( buf, portal->description, to_room->name );
  free_string( portal->description );
  portal->description = str_dup( buf );
  sprintf( buf, portal->short_descr, to_room->name );
  free_string( portal->short_descr );
  portal->short_descr = str_dup( buf );
  obj_to_room (portal, from_room);

  act ("{c$n tears a rift through space and $p appears.{x", ch, portal, NULL, TO_ROOM);
  act ("{cYou tear a rift through space and $p appears.{x", ch, portal, NULL, TO_CHAR);
}

/*
#24
nexus~
a shimmering nexus~
A shimmering magical nexus to %s is here.~
~
29 0 0
0~ 0~ 0~ 0~
100 0 0
*/

void spell_nexus (int sn, int level, CHAR_DATA * ch, void *vo, int target)
{
  char buf[MAX_INPUT_LENGTH];
  CHAR_DATA *victim;
  OBJ_DATA *portal;
  ROOM_INDEX_DATA *to_room, *from_room;

  from_room = ch->in_room;

  if ((victim = get_char_world (ch, target_name)) == NULL || victim == ch
      || (to_room = victim->in_room) == NULL
      || IS_SET (to_room->room_flags, ROOM_SAFE)
      || IS_SET (to_room->room_flags, ROOM_PRIVATE)
      || IS_SET (to_room->room_flags, ROOM_NO_PORTAL)
      || IS_SET (from_room->room_flags, ROOM_NO_PORTAL)
      || victim->level >= level + 3 || (!IS_NPC (victim)
					&& victim->level >= LEVEL_HERO)
      || (IS_NPC (victim) && saves_spell (level, victim)))
  {
    send_to_char ("Your spell fizzles.\n\r", ch);
    return;
  }

  portal = create_object (get_obj_index (OBJ_VNUM_NEXUS), 0);
  portal->timer = 1 + level / 10;
  portal->value[3] = to_room->vnum;
  sprintf (buf, portal->description, to_room->name);
  free_string (portal->description);
  portal->description = str_dup (buf);
  sprintf (buf, portal->short_descr, to_room->name);
  free_string (portal->short_descr);
  portal->short_descr = str_dup (buf);
  obj_to_room (portal, from_room);

  act ("{c$n tears a rift through space and $p appears.{x", ch, portal, NULL,
       TO_ROOM);
  act ("{cYou tear a rift through space and $p appears.{x", ch, portal, NULL,
       TO_CHAR);

  if (to_room == from_room)
    return;

  portal = create_object (get_obj_index (OBJ_VNUM_NEXUS), 0);
  portal->timer = 1 + level / 10;
  portal->value[3] = from_room->vnum;
  sprintf (buf, portal->description, from_room->name);
  free_string (portal->description);
  portal->description = str_dup (buf);
  sprintf (buf, portal->short_descr, from_room->name);
  free_string (portal->short_descr);
  portal->short_descr = str_dup (buf);
  obj_to_room (portal, to_room);

  if (to_room->people != NULL)
  {
    act ("{c$n tears a rift through space and $p appears.{x", to_room->people,
	 portal, NULL, TO_ROOM);
    act ("{c$n tears a rift through space and $p appears.{x", to_room->people,
	 portal, NULL, TO_CHAR);
  }

}


// Merc 2.2 didn't have do_enter but here is what I use.. You will notice
// in the code below, there is also a check for NEXUS.. Basicly, just grep
// your source code and add an ITEM_NEXUS below ITEM_PORTAL if you want. I
// did this so that I can set ITEM_NEXUS within OLC so that I can have a
// seperate message for then the portal / nexus is extracted. (See Below)


/*
 *	This is a quick hack of Rom's do_enter code for use with portal and nexus.
 */

void do_enter (CHAR_DATA * ch, char *argument)
{
  OBJ_DATA *portal;
  ROOM_INDEX_DATA *location;

  if (ch->fighting != NULL)
    return;

  portal = get_obj_list (ch, argument, ch->in_room->contents);

  if (portal == NULL)
  {
    send_to_char ("{gYou don't see that here.{x\n\r", ch);
    return;
  }

  if (portal->item_type != ITEM_PORTAL && portal->item_type != ITEM_NEXUS)
  {
    send_to_char ("{gYou can't seem to find a way in.{x\n\r", ch);
    return;
  }

  location = get_room_index (portal->value[3]);

  if (location == NULL)
  {
    act ("{g$p doesn't seem to go anywhere.{x", ch, portal, NULL, TO_CHAR);
    return;
  }

  act ("{g$n enters $p{x", ch, portal, NULL, TO_ROOM);
  char_from_room (ch);
  char_to_room (ch, location);
  act ("{g$n appears into the room{x", ch, NULL, NULL, TO_ROOM);
  do_look (ch, "auto");

  /*
   * If someone is following the char, these triggers get activated
   * for the followers before the char, but it's safer this way...
   */
  if (IS_NPC (ch) && HAS_TRIGGER (ch, TRIG_ENTRY))
    mp_percent_trigger (ch, NULL, NULL, NULL, TRIG_ENTRY);
  if (!IS_NPC (ch))
    mp_greet_trigger (ch);

  return;
}

// Other code bits.. 

// Update.c (void obj_update)

    case ITEM_PORTAL:
	  message = "{gThe portal crackles suddenly, flares brightly, and is gone!{x";
      break;
    case ITEM_NEXUS:
      message = "{gThe room shudders as the nexus implodes in on itself and vanishes!{x";
      break;

// My modded merc 2.2 files are dif from Rom but the code should be simular. Just
// search for the portal counterpart and add the Nexus addition.

!  {"portal", ITEM_PORTAL, TRUE},
+  {"nexus", ITEM_NEXUS, TRUE},


!  {ITEM_PORTAL, "portal"},
+  {ITEM_NEXUS, "nexus"},

// db.c?
!  case ITEM_PORTAL:
+  case ITEM_NEXUS:

// merc.h - Rom should have this... Once you add all of the above
// code, use OLC to change the type flag on Nexus from type portal to type Nexus..
// Nothing else needs to be changed.

#define ITEM_NEXUS		     14 /* <- some available num */