ka_hotspot_click_force

The script ka_hotspot_click_force gets called when the devs needed to make sure a certain NPC is along for the ride. Otherwise, it seems to work very similar to ka_hotspot_click.

I've removed a number of the plot checks to avoid spoilers.

// ka_hotspot_click_force
//
// Action script for when a hotspot is clicked on the worldmap.  Determines the location to send
// the party to.  This variant checks a global variable sCompVar, and if it's equal to nCheckValue, 
// fires a message box instead of sending the player on.  That message box is defined in this file 
// as well, in DisplayForceCompanionMessage.  The nMessage parameter chooses what message box to use.

// EPF 1/10/06
// TDE 1/31/06 - Added messages for Act 3, and scripting for if any one of a list of companions is required.
// EPF 1/31/06 - Using IsInParty instead of GetIsRosterMemberAvailable().
// TDE 3/23/06 - Fixed a bug in the companion list script
// EPF 3/29/06 -- uses JumpPartyToArea now
// BMA-OEI 4/12/06 - replaced LoadNewModule() with SaveRosterLoadModule()
// TDE 4/25/06 - Added support for excluding companions using "-" instead of ","

#include "kinc_worldmap"
#include "ginc_debug"
#include "ginc_companions"
#include "ginc_transition"

// Each case here needs to do the following, in this order:
// 1. Set a global string "00_sLastForcedCompanion" to be the roster name of the companion you're forcing to join.
// 2. Display a message box.  Callback script is always gui_force_comp.
//
// TDE - Eric, if this becomes a permanent solution rather than temp, these strings will need to be 
//		 added to dialog.tlk and called with SpeakStringByStrRef(nNum)

void DisplayForceCompanionMessage(int nMessage)
{
	object oPC = OBJECT_SELF;
	switch(nMessage)
	{
	case 1:
		//You must have xin your party in order to travel to y. Proceed?
		SetGlobalString("00_sLastForcedCompanion", "sand");
		DisplayMessageBox(oPC,178912, "", "gui_force_comp","",TRUE,"SCREEN_MESSAGEBOX_DEFAULT",66,"",67);
		break

        // PLOT CHECKS REMOVED HERE!!!!

	}
}
	
void main(string sModule, string sHotspot, int nProbSpecial, int nProbRandom, string sCompanion, string sCompVar, int nCheckValue, int nMessage)
{
	string sDestination;
	object oDestination;
	int nRoll;
	object oPC = OBJECT_SELF;
	object oFirstPC = GetFirstPC();
	object oFM;
	
	if(!GetIsSinglePlayer())
	{
		if(GetWorldMapLocked())
		{
			SendMessageToPC(oPC, GetStringByStrRef(STRING_REF_MAP_LOCKED));
			return;
		}
		else
		{
			SetWorldMapLocked();
		}
	}
		
	//companion is supposed to be forced at this point
	if ( GetGlobalInt(sCompVar) == nCheckValue ) 
	{	
		// Added by TDE: to allow passing in a list such as "zhjaeve,ammon_jerro"
	    int iLen;
	    int iCommaPos = FindSubString( sCompanion, "," ); //find first comma
	    int iMinusPos = FindSubString( sCompanion, "-" ); //find first minus
		int bDisplayMessage = TRUE; //Display the message if is a required companion is NOT in party or an excluded companion is in the party

		if ( iCommaPos == -1 && iMinusPos == -1 )
		{
			//only checking for one companion
			if(IsInParty(sCompanion))	
			{
				bDisplayMessage = FALSE;
			}
		}
		else
		{
			//Checking for multiple companions
			//PrettyMessage("Checking for multiple companions");
			string sNewString = sCompanion;
			int iPosEnd;
			int iPosStart;
			int bExclude;
	
		    while ( iCommaPos != -1 || iMinusPos != -1 )
		    {
			//	PrettyDebug("Trying to find " + sNewString);

		        // determine length
		        iLen = GetStringLength(sNewString);

			    // get next comma or - position (returns -1 if not found)
		        iCommaPos = FindSubString(sNewString, "," );
				iMinusPos = FindSubString(sNewString, "-" );
				bExclude = FALSE;

				if ( iCommaPos == -1 && iMinusPos == -1 )
				{
					iPosStart = 0;
					iPosEnd = iLen;
				}
				else
				{
					if ( iMinusPos != -1 && (iCommaPos == -1 || iCommaPos > iMinusPos) ) 
					{
						PrettyDebug("Minus Pos = " + IntToString(iMinusPos));

						bExclude = TRUE;
						iPosStart = iMinusPos + 1;	// Minus is the next in the sequence
						if (iCommaPos > iMinusPos) 
							iPosEnd = iCommaPos - 1;
						else iPosEnd = iLen;
					}
					else
					{
					//	PrettyDebug("Comma Pos = " + IntToString(iCommaPos));
						iPosStart = 0;
						iPosEnd = iCommaPos;	// Comma is the next in the sequence
					}
				}
	
		        // get companion name in string
		        string sTempString = GetSubString(sNewString, iPosStart, iPosEnd);

				PrettyMessage("Getting " + sTempString);	

				// If this companion is in the party, set flag
				if ( IsInParty(sTempString) )
				{
					//PrettyDebug(sTempString + " is in the party.");
					if ( bExclude )
					{
					//	PrettyDebug(sTempString + " should NOT be in the party.");
						// Make sure they are selectable, so they can be removed from the party
						SetIsRosterMemberSelectable(sTempString,TRUE);
						bDisplayMessage = TRUE;
						break;
					}
					else 
					{
						PrettyDebug(sTempString + " should be in the party.");
						bDisplayMessage = FALSE;
					}
				}
				else PrettyDebug(sTempString + " is NOT in the party.");	
	
		        // drop first tag and comma
				if ( bExclude )
				{
				//	PrettyDebug("Getting index between zero and" + IntToString(iMinusPos));
			        sNewString  = GetSubString(sNewString, 0, iMinusPos);
				}	
		        	
				else 
				{
				//	PrettyDebug("Getting index between " + IntToString(iPosEnd + 1) + " and " + IntToString(iLen));
		        	sNewString  = GetSubString(sNewString, iPosEnd + 1, iLen);
				}
		    }
		}

		if( bDisplayMessage )
		{
		//	PrettyDebug("Displaying Force Companion Message.");
			DisplayForceCompanionMessage(nMessage);
			return;
		}
	}
	
	//we only want one map encounter per player attempt to travel --
	//prevents the player getting barraged by module cutscenes
	//when he just wants to get to point B.
	if(!GetGlobalInt("bPlayedEncounterOnThisClick"))
	{
		 sDestination = GetModuleEncounter(sModule, sHotspot);
	
		if(sDestination == "")
		{
			nRoll = Random(100);
	
			if(nRoll < nProbSpecial)
			{
				sDestination = GetSpecialEncounter(sModule, sHotspot);	
			}
			else if(nRoll < nProbSpecial + nProbRandom)
			{
				sDestination = GetRandomEncounter(sModule, sHotspot);
			}
		}
	}
	if(sDestination == "")
	{
		SetGlobalInt("bPlayedEncounterOnThisClick",FALSE);
		sDestination = GetDefaultDestination(sHotspot);
	}
	else	//we're doing an encounter
	{
		SetGlobalInt("bPlayedEncounterOnThisClick",TRUE);
		// unless our present encounter overrides the message with a global variable, we play it 
		// and return.
		if(!GetGlobalInt(ENCOUNTER_MESSAGE_OVERRIDE))
		{
			ShowEncounterMessage(sDestination, sModule);
			return;
		}
		SetGlobalInt(ENCOUNTER_MESSAGE_OVERRIDE, FALSE);		
	}
	
	//this variable handles origin-dependent redirection, like changing the point of
	//entry in the docks district depending on whether you came from blacklake
	//or the merchant quarter.  We reset it to its default here.  It is set in the 
	//cliententer scripts of applicable areas.
	SetGlobalInt("OriginArea",0);	
	
	oDestination = GetObjectByTag(sDestination);
		
	if(GetIsObjectValid(oDestination))
	{
		ForceRestParty( oPC );
		// BMA-OEI 6/14/06
		SinglePartyTransition( oPC, oDestination );
		//JumpPartyToArea(oPC, oDestination);
	}
	else
	{
		ForceRestParty( oPC );
		PrettyDebug("Unable to find waypoint in current module.  Initiating module transition.");
		//LoadNewModule(sModule, sDestination);
		SaveRosterLoadModule(sModule, sDestination);
	}
	
}