Problem with script - Switch to owned character

So, I have a script, originally made by KevL_s, that I’ve modified. It’s a script attached to a Area Transition. If you controll your own character clicking the Area Transition everything works fine, but when controlling a companion it doesn’t work as I want it to. I would want to switch control to the owned character if one clicks on the Area Transition, and thus making the script work as intended. However, as the script looks now the game wont switch to the owned character. I’ve tried different things for a long while now but nothing seems to work. I found another thread about a similar thing by Aqvilinus, and I tried what he wrote about there, but…it didn’t help…

Here is the script:

const string sDEST_PC       = "hang_wp"; // waypoint tag of the PC's destination
const string sDEST_SNOFWIN 	= "hangout_camp_snofwin"; // waypoint tag of the Companions' destination
const string sDEST_TYN 		= "hangout_camp_tyn"; // waypoint tag of the Companions' destination
const string sDEST_VALERIE 	= "hangout_camp_valerie"; // waypoint tag of the Companions' destination
const string sDEST_ANELIA	= "hangout_camp_anelia"; // waypoint tag of the Companions' destination
const string sDEST_GARDOK	= "hangout_camp_gardok"; // waypoint tag of the Companions' destination
const string sDEST_MEAH 	= "hangout_camp_meah"; // waypoint tag of the Companions' destination

void SwitchControl(object oControlled)
{
    SetOwnersControlledCompanion(oControlled);
}

void main()
{
    object oEnter = GetClickingObject();
	object oPC = GetOwnedCharacter(GetFactionLeader(oEnter));

    AssignCommand(oPC, ClearAllActions(TRUE));
	
    object oDestSnofwin = GetWaypointByTag(sDEST_SNOFWIN);
	object oDestTyn = GetWaypointByTag(sDEST_TYN);
	object oDestValerie = GetWaypointByTag(sDEST_VALERIE);
	object oDestAnelia = GetWaypointByTag(sDEST_ANELIA);
	object oDestGardok = GetWaypointByTag(sDEST_GARDOK);
	object oDestMeah = GetWaypointByTag(sDEST_MEAH);
	
    string sRoster;
    string sRosterListCurrent = "";
	
    object oFaction = GetFirstFactionMember(oEnter, FALSE);
	
   	DelayCommand(0.0f, SwitchControl(GetControlledCharacter(oPC)));
	

	
	if (GetIsOwnedByPlayer(oEnter))
	{
   	 while (GetIsObjectValid(oFaction))
    	{
        sRoster = GetRosterNameFromObject(oFaction);
        
			if (sRoster == "snofwin")
        	{
            sRosterListCurrent += sRoster + ";";

            if (GetIsPC(oFaction))
                SetOwnersControlledCompanion(oFaction);

            RemoveRosterMemberFromParty(sRoster, oEnter, FALSE);

            AssignCommand(oFaction, ClearAllActions());
            AssignCommand(oFaction, JumpToObject(oDestSnofwin));


            oFaction = GetFirstFactionMember(oEnter, FALSE);
       		 }
		
		if (sRoster == "tyn")
       		 {
            sRosterListCurrent += sRoster + ";";

            if (GetIsPC(oFaction))
                SetOwnersControlledCompanion(oFaction);

            RemoveRosterMemberFromParty(sRoster, oEnter, FALSE);

            AssignCommand(oFaction, ClearAllActions());
            AssignCommand(oFaction, JumpToObject(oDestTyn));


            oFaction = GetFirstFactionMember(oEnter, FALSE);
      	 	 }
		
		if (sRoster == "valerie")
       		 {
            sRosterListCurrent += sRoster + ";";

            if (GetIsPC(oFaction))
                SetOwnersControlledCompanion(oFaction);

            RemoveRosterMemberFromParty(sRoster, oEnter, FALSE);

            AssignCommand(oFaction, ClearAllActions());
            AssignCommand(oFaction, JumpToObject(oDestValerie));


            oFaction = GetFirstFactionMember(oEnter, FALSE);
      		  }
		
		if (sRoster == "anelia")
     	   {
            sRosterListCurrent += sRoster + ";";

            if (GetIsPC(oFaction))
                SetOwnersControlledCompanion(oFaction);

            RemoveRosterMemberFromParty(sRoster, oEnter, FALSE);

            AssignCommand(oFaction, ClearAllActions());
            AssignCommand(oFaction, JumpToObject(oDestAnelia));


            oFaction = GetFirstFactionMember(oEnter, FALSE);
      		  }
		
		if (sRoster == "gardok")
      		  {
            sRosterListCurrent += sRoster + ";";

            if (GetIsPC(oFaction))
                SetOwnersControlledCompanion(oFaction);

            RemoveRosterMemberFromParty(sRoster, oEnter, FALSE);

            AssignCommand(oFaction, ClearAllActions());
            AssignCommand(oFaction, JumpToObject(oDestGardok));


            oFaction = GetFirstFactionMember(oEnter, FALSE);
     	   }
		
		if (sRoster == "meah")
    	    {
            sRosterListCurrent += sRoster + ";";

            if (GetIsPC(oFaction))
                SetOwnersControlledCompanion(oFaction);

            RemoveRosterMemberFromParty(sRoster, oEnter, FALSE);

            AssignCommand(oFaction, ClearAllActions());
            AssignCommand(oFaction, JumpToObject(oDestMeah));


            oFaction = GetFirstFactionMember(oEnter, FALSE);
    	    }
		
	
        else
            oFaction = GetNextFactionMember(oEnter, FALSE);
  		  }
	}
    if (sRosterListCurrent != "")
        SetLocalString(oEnter, "CurrentRosterList", sRosterListCurrent);
		
	SetLocalInt(oEnter,"gotocamp",GetLocalInt(oEnter,"gotocamp")+1);
		
    AssignCommand(oEnter, ClearAllActions());
    AssignCommand(oEnter, JumpToObject(GetWaypointByTag(sDEST_PC)));
}

looking …

a couple things strike me off the bat,

if you want the player shunted to his OwnedChar before the jumps, the call to SwitchControl() shouldn’t be wrapped in a delay. And, to keep the iterator in sync, the roster-checks should be using elseif()

will simplify and see what stands out

// 'andgalf_tr'

const string sDEST_PC      = "hang_wp";                 // tag of PC's hangout Wp
const string sDEST_SNOFWIN = "hangout_camp_snofwin";    // tags of Co's hangout Wps ->
const string sDEST_TYN     = "hangout_camp_tyn";
const string sDEST_VALERIE = "hangout_camp_valerie";
const string sDEST_ANELIA  = "hangout_camp_anelia";
const string sDEST_GARDOK  = "hangout_camp_gardok";
const string sDEST_MEAH    = "hangout_camp_meah";

// script vars
object _oPc;
object _oParty;
string _sRoster;

string _sRosterListCurrent;

void transition(string sDest);

//
void main()
{
    _oPc = SetOwnersControlledCompanion(GetClickingObject());

    _oParty = GetFirstFactionMember(_oPc, FALSE);
    while (GetIsObjectValid(_oParty))
    {
        _sRoster = GetRosterNameFromObject(_oParty);

        if (_sRoster == "snofwin")
        {
            transition(sDEST_SNOFWIN);
            _oParty = GetFirstFactionMember(_oPc, FALSE);
        }
        else if (_sRoster == "tyn")
        {
            transition(sDEST_TYN);
            _oParty = GetFirstFactionMember(_oPc, FALSE);
        }
        else if (_sRoster == "valerie")
        {
            transition(sDEST_VALERIE);
            _oParty = GetFirstFactionMember(_oPc, FALSE);
        }
        else if (_sRoster == "anelia")
        {
            transition(sDEST_ANELIA);
            _oParty = GetFirstFactionMember(_oPc, FALSE);
        }
        else if (_sRoster == "gardok")
        {
            transition(sDEST_GARDOK);
            _oParty = GetFirstFactionMember(_oPc, FALSE);
        }
        else if (_sRoster == "meah")
        {
            transition(sDEST_MEAH);
            _oParty = GetFirstFactionMember(_oPc, FALSE);
        }
        else
            _oParty = GetNextFactionMember(_oPc, FALSE);
    }

    if (_sRosterListCurrent != "")
        SetLocalString(_oPc, "CurrentRosterList", _sRosterListCurrent);

    SetLocalInt(_oPc, "gotocamp", GetLocalInt(_oPc, "gotocamp") + 1);

    AssignCommand(_oPc, ClearAllActions());
    AssignCommand(_oPc, JumpToObject(GetWaypointByTag(sDEST_PC)));
}

//
void transition(string sDest)
{
    _sRosterListCurrent += _sRoster + ";";

    RemoveRosterMemberFromParty(_sRoster, _oPc, FALSE);

    AssignCommand(_oParty, ClearAllActions());
    AssignCommand(_oParty, JumpToObject(GetWaypointByTag(sDest)));
}

 
 
hm, should probly delete the CurrentRosterList if it’s empty - so it doesn’t carry over from a previous setting.

1 Like

Thank you kevL_s! That worked splendidly.

How do one delete the CurrentRosterList, if I may ask? (I think I’m slowly getting better at understanding scripting, but I still have a long way to go)

The thing you pointed out about the delay… That’s a little embarrassing, actually. I tried with just “SwitchControl(GetControlledCharacter(oPC));” but that didn’t compile so…and now that I tested with that line again it does compile. Strange. Anyway, that was why I felt compelled to use DelayCommand 'cause that compiled.

Edit: Looking at it again I now remember using this “AssignCommand(SwitchControl(GetControlledCharacter(oPC)));” and that’s why it didn’t compile, I think. I’m still not sure when to use the AssignCommand. It says in the description it has to do with an action, and maybe there’s specific actions they refer to when you’re to use that…

1 Like
    if (_sRosterListCurrent != "")
        SetLocalString(_oPc, "CurrentRosterList", _sRosterListCurrent);
    else
        DeleteLocalString(_oPc, "CurrentRosterList");

read code like a book. You don’t even have to understand it… just slow down and read it word by word, sentence by sentence, paragraph by paragraph.

uh not good enough. Taking stabs in the dark with computer code works about 0.0001% of the time.

The classic example is

AssignCommand(oPc, ClearAllActions());

That’s because ClearAllActions() needs an object to work on but doesn’t take an argument for such object. So NwScript is designed to always work on OBJECT_SELF, by default. But by wrapping a function-call in AssignCommand(), it tells the engine that, hey, you’re changing the definition of OBJECT_SELF for that call

OBJECT_SELF is considered to be the “owner” of its script. if self doesn’t exist, the script won’t even run. So a second example is, if you want something to happen say 5 seconds after an OnDeath event – you’d have to wrap a Delayed command in a command that’s Assigned to a different owner … eg, the module object … since dead creatures won’t run scripts either.

etc. It just passes the duties of a function-call off to a different object.


oh, and if you want, the line(s)

    _oParty = GetFirstFactionMember(_oPc, FALSE);

could all be moved to a single line at the very end of transition() ( since ‘_oParty’ was declared as a script-variable )

If You’re having problems with scripting, there are some scripting tutorials out there that could help. Goodness knows I needed them. Now I need them less :slight_smile:

1 Like

(Deleted post)