Author: Phalzyr
Author Website: n/a
Script Name: Multiple Portals
Description: This script allows you to activate a portal and be given a selection of portal destinations once a portal has been activated. 

It does not portal henchmen with you.  NOTE: If you want the script to work with henchmen go to Script 2 below and replace the functions in Script 1 with those in Script 2. 

If the PC is in battle they will not be given a selection but instead be taken to the primary portal location.

Instructions on Use: See instructions in script comments.

Script 1:
*Note:  There are many scripts contained in the below text box not just one.  Read through the comments to determine where new scripts are located.

//First i should say most of this script are attached
//to conversation events, and in my case I made the
//conversation name "recallchoices" and also any object
//name below starting with RP_ is recall portal and you
//should alter names as needed.
//
//Z1_activateportal
//This function goes in the first conversation line
//as an action wish I could post my conersation also
//it simply sets the portal so that you can use it.
void main()
{
    SetLocalInt(OBJECT_SELF,"M1_PORTAL_ACTIVATED",TRUE);
}
//z1_include
//I used this in my include file so I wouldn't
//have to retype in every other script.
//This will send the user to the selected
//portal, and set the recall location.
//
void mygotoportal(string stag)
{
  object oPC = GetPCSpeaker();
  object oPortal = GetObjectByTag(stag);
  if (GetIsObjectValid(oPortal) == TRUE) {
    if (GetObjectType(OBJECT_SELF) != OBJECT_TYPE_PLACEABLE) {
      SetLocalInt(oPC,"NW_L_USED_RECALL",1);
      SetLocalLocation(oPC,"NW_L_LOC_RECALL",GetLocation(oPC));
    }
    AssignCommand(oPC,ClearAllActions());
    AssignCommand(oPC,PlaySound("as_mg_telepout1"));
    AssignCommand(oPC,JumpToObject(oPortal));
    AssignCommand(oPC,ActionDoCommand(ClearAllActions()));
  } else  {
    AssignCommand(oPC,ActionSpeakStringByStrRef(10614));
  }
}
//This will send the user to the selected
//portal during battle, and set the recall location.
//notice I have a separate storage for battle recall
//and conversation recall :)
void mygotoportalb(string stag)
{
  object oPC = GetItemActivator();
  object oPortal = GetObjectByTag(stag);
  if (GetIsObjectValid(oPortal) == TRUE) {
    SetLocalInt(oPC,"NW_L_USED_RECALLB",1);
    SetLocalLocation(oPC,"NW_L_LOC_RECALLB",GetLocation(oPC));
    AssignCommand(oPC,ClearAllActions());
    AssignCommand(oPC,PlaySound("as_mg_telepout1"));
    AssignCommand(oPC,JumpToObject(oPortal));
    AssignCommand(oPC,ActionDoCommand(ClearAllActions()));
  } else  {
    AssignCommand(oPC,ActionSpeakStringByStrRef(10614));
  }
}


//z1_itemactivated
//this code should be placed in whatever script you are
//running in your modules's on item actived slot.
//it simply tells what to do when the stone is used:
//start conersation if not in batttle other wise
//go to the primary portal in my case is
//"RP_DELADES_TEMPLE" rename it if neccessary.
#include "z1_include"


void main()
{
  string stag = GetTag(GetItemActivated());
  if (stag == "NW_IT_RECALL") {
    if (!GetIsInCombat(GetItemActivator()) || (!GetLocalInt(GetObjectByTag("RP_DELADES_TEMPLE"),"M1_PORTAL_ACTIVATED"))) {
      AssignCommand(GetItemActivator(),ActionStartConversation(GetItemActivator(),"recallchoices",TRUE));
    } else {
       mygotoportalb("RP_DELADES_TEMPLE");
    }
  }
}
//pc_deladestemple
//this is a dialog conditonal check to see if the portal
//has been activated, you'll need one for each portal
//you have and alter the stag as needed.
//In my case I made an option in the conversation to be
//Delade's Temple, and on its "appear when" put this.
int StartingConditional()
{
    string stag = "RP_DELADES_TEMPLE";
    int iResult = GetLocalInt(GetObjectByTag(stag),"M1_PORTAL_ACTIVATED");
    if (GetTag(OBJECT_SELF) == stag) {
      iResult = FALSE; }
    return iResult;
}
//pc_recallstone
//this is a dialog conditonal check to see if the stone
//has been used during conversation.
//In my case I made an option in the conversation to be
//Go back to last location stone was used during
//conversation, and on its "appear when" put this.
int StartingConditional()
{
    int iResult = GetLocalInt(GetPCSpeaker(), "NW_L_USED_RECALL");
    return iResult;
}
//pc_recallstoneb
//this is a dialog conditonal check to see if the stone
//has been used during combat.
//In my case I made an option in the conversation to be
//Go back to last location stone was used during
//combat, and on its "appear when" put this.
int StartingConditional()
{
    int iResult = GetLocalInt(GetPCSpeaker(), "NW_L_USED_RECALLB");
    return iResult;
}
//ps_deladestemple
//this sends the pc to the portal
//simply attach this to the dialogs action slot.
//you need one for each portal change string as needed!
#include "z1_include"
void main()
{
  mygotoportal("RP_DELADES_TEMPLE");
}
//ps_recallstone
//this sends the pc to the spot you last used the stone
//during conversation.
//simply attach this to the dialogs action slot.
void main()
{
   object oPC = GetPCSpeaker();
   location lLoc = GetLocalLocation(oPC, "NW_L_LOC_RECALL");
   SetLocalInt(oPC, "NW_L_LOC_EVERUSED", 1);
   SetLocalLocation(oPC, "NW_L_LOC_LAST_RECALL", lLoc);
   ApplyEffectAtLocation(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_IMP_UNSUMMON), lLoc);
   AssignCommand(oPC, JumpToLocation(lLoc));
}
//ps_recallstoneb
//this sends the pc to the spot you last used the stone
//during combat.
//simply attach this to the dialogs action slot.
void main()
{
   object oPC = GetPCSpeaker();
   location lLoc = GetLocalLocation(oPC, "NW_L_LOC_RECALLB");
   SetLocalInt(oPC, "NW_L_LOC_EVERUSED", 1);
   SetLocalLocation(oPC, "NW_L_LOC_LAST_RECALL", lLoc);
   ApplyEffectAtLocation(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_IMP_UNSUMMON), lLoc);
   AssignCommand(oPC, JumpToLocation(lLoc));
}

Script 2 (Updates for allowing Henchmen to portal as well):

//z1_include
//replace the same functions in my earlier script with these
void mygotoportal(string stag)
{
  object oPC = GetPCSpeaker();
  object oPortal = GetObjectByTag(stag);
  if (GetIsObjectValid(oPortal) == TRUE) {
    if (GetObjectType(OBJECT_SELF) != OBJECT_TYPE_PLACEABLE) {
      SetLocalInt(oPC,"NW_L_USED_RECALL",1);
      SetLocalLocation(oPC,"NW_L_LOC_RECALL",GetLocation(oPC));
    }
    AssignCommand(oPC,ClearAllActions());
    AssignCommand(oPC,PlaySound("as_mg_telepout1"));
    AssignCommand(oPC,JumpToObject(oPortal));
    object oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC);
    object oAnimal = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION,oPC);
    object oFamiliar = GetAssociate(ASSOCIATE_TYPE_FAMILIAR,oPC);
    object oDominated = GetAssociate(ASSOCIATE_TYPE_DOMINATED,oPC);
    object oSummoned = GetAssociate(ASSOCIATE_TYPE_SUMMONED,oPC);
    if (GetIsObjectValid(oHenchman))
      AssignCommand(oHenchman,JumpToObject(oPortal));
    if (GetIsObjectValid(oAnimal))
      AssignCommand(oAnimal,JumpToObject(oPortal));
    if (GetIsObjectValid(oFamiliar))
      AssignCommand(oFamiliar,JumpToObject(oPortal));
    if (GetIsObjectValid(oDominated))
      AssignCommand(oDominated,JumpToObject(oPortal));
    if (GetIsObjectValid(oSummoned))
      AssignCommand(oSummoned,JumpToObject(oPortal));
    AssignCommand(oPC,ActionDoCommand(ClearAllActions()));
  } else  {
    AssignCommand(oPC,ActionSpeakStringByStrRef(10614));
  }
}
//  mygotoportalb - onused/activated item - This will send the user to the selected
//portal during battle, and set the recall location.
//
void mygotoportalb(string stag)
{
  object oPC = GetItemActivator();
  object oPortal = GetObjectByTag(stag);
  if (GetIsObjectValid(oPortal) == TRUE) {
    SetLocalInt(oPC,"NW_L_USED_RECALLB",1);
    SetLocalLocation(oPC,"NW_L_LOC_RECALLB",GetLocation(oPC));
    AssignCommand(oPC,ClearAllActions());
    AssignCommand(oPC,PlaySound("as_mg_telepout1"));
    AssignCommand(oPC,JumpToObject(oPortal));
    object oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC);
    object oAnimal = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION,oPC);
    object oFamiliar = GetAssociate(ASSOCIATE_TYPE_FAMILIAR,oPC);
    object oDominated = GetAssociate(ASSOCIATE_TYPE_DOMINATED,oPC);
    object oSummoned = GetAssociate(ASSOCIATE_TYPE_SUMMONED,oPC);
    if (GetIsObjectValid(oHenchman))
      AssignCommand(oHenchman,JumpToObject(oPortal));
    if (GetIsObjectValid(oAnimal))
      AssignCommand(oAnimal,JumpToObject(oPortal));
    if (GetIsObjectValid(oFamiliar))
      AssignCommand(oFamiliar,JumpToObject(oPortal));
    if (GetIsObjectValid(oDominated))
      AssignCommand(oDominated,JumpToObject(oPortal));
    if (GetIsObjectValid(oSummoned))
      AssignCommand(oSummoned,JumpToObject(oPortal));
    AssignCommand(oPC,ActionDoCommand(ClearAllActions()));
  } else  {
    AssignCommand(oPC,ActionSpeakStringByStrRef(10614));
  }
}