I have a vague memory of @Lance_Botelle solving this somehow in some way in a thread where we discussed this maybe 2 years ago, but I can’t find it.
I have a situation in my module where I would like it so that the Main PC is somehow “invisible” (the clicking aspect with the portrait and all), and the player is forced to just controll the companions in the party. I think this might be close to impossible, but then again, I have some vague memory of @Lance_Botelle showing some video where he had accomplished this.
The only thing I could find when trying to locate earlier threads is this:
Maybe what I remember is Lance hiding all the portraits and showing that in a video.
EDIT: Lance found the video and showed me. He was hiding all the portraits. I will still put this thread here if someone somehow has a solution.
So…Lance told me to use the stock script gb_player_ud and make a new version of that as a campaign script. So that when the player tries to controll the PC it reverts to one of the companions instead. So, at the end of a dialogue, I change the controlled character to one of the companions. That works. But then when switching to the main PC, the game won’t switch to the companion even though I’m using my version of gb_player_ud. It just won’t switch to the companion. The script is running and all that, but somehow what I have coded doesn’t do what I want it to. For some odd reason the game seems to think that oNewMain is the same as the default PC. I have tried with an if statement using GetControlledCharacter but then the game engine whines about it looking for an integer…Uugh! What small mistake am I making here? I don’t get it. What function am I supposed to use for this to work. Darn stupid scripting and all it’s peculiarities in needing to use just the right thing for anything to work!
// gb_player_ud
/*
user defined events template
*/
// ChazM 9/5/06 don't have leader follow himself
// BMA-OEI 09/12/06 -- Added EVENT_PLAYER_CONTROL_CHANGED handler
// MDiekmann 8/7/07 - Modified to run a custom user defined script based on the tag if one exists
#include "ginc_companion"
#include "ginc_debug"
#include "ginc_overland"
#include "x0_i0_assoc"
#include "hench_i0_assoc"
// this includes: GetFollowDistance()
void ResetPC(object oNewMain)
{
object oPC = SetOwnersControlledCompanion(OBJECT_SELF, oNewMain);
}
void main()
{
string sMyTag = GetTag(OBJECT_SELF);
int iEvent = GetUserDefinedEventNumber();
// Jug_Debug(GetName(OBJECT_SELF) + " event num " + IntToString(iEvent));
//execute custom user-defined script from local string if it exists
string sUDScript=GetLocalString(OBJECT_SELF, "ud_script");
if (sUDScript != "")
{
ExecuteScript(sUDScript, OBJECT_SELF);
}
switch (iEvent)
{
case EVENT_HEARTBEAT: // 1001
break;
case EVENT_PERCEIVE: // 1002
break;
case EVENT_END_COMBAT_ROUND: // 1003
break;
case EVENT_DIALOGUE: // 1004
break;
case EVENT_ATTACKED: // 1005
break;
case EVENT_DAMAGED: // 1006
break;
case EVENT_DISTURBED: // 1008
break;
case EVENT_SPELL_CAST_AT: // 1011
break;
case EVENT_PLAYER_CONTROL_CHANGED:
{
if(GetGlobalInt("chicken"))
{
//object oOldActor = GetFirstPC();
object oNewMain = GetFirstPC(FALSE);
DelayCommand(0.1, ResetPC(oNewMain));
}
break;
}
// 2052
case EVENT_TRANSFER_PARTY_LEADER:
{
if(GetIsOverlandMap(GetArea(OBJECT_SELF)))
{
PrettyDebug("gb_player_ud firing for" + GetName(OBJECT_SELF));
object oOldActor = GetLocalObject(GetModule(), "oPartyLeader");
if(GetIsPC(OBJECT_SELF) && oOldActor != OBJECT_SELF)
{
if(GetCommandable(OBJECT_SELF) && !GetIsDead(OBJECT_SELF) &&
(GetIsRosterMember(OBJECT_SELF) || GetIsOwnedByPlayer(OBJECT_SELF)) )
{
SetPartyActor(OBJECT_SELF);
}
else
SetPartyActor(oOldActor, OBJECT_SELF);
}
}
if(GetAssociateState(NW_ASC_MODE_PUPPET) == TRUE)
break;
// Jug_Debug(GetName(OBJECT_SELF) + " handle player control change");
HenchHandlePlayerControlChanged(OBJECT_SELF);
break;
}
}
}
Doesn’t make sense to me. I mean, I want to switch the controlled character to every other character BUT the main PC. I’ll try it anyway even if it defies all logic.
EDIT: Just as I thought. At least this time my logic was the same as the game’s logic. Now when using GetFirstPC(TRUE) it switches back to the main PC and that’s the opposite of what I want. How do I get the game to switch back to the last controlled character instead? I don’t get it? Why doesn’t it work?
Ok, I hear you and see it now. Not easy when scrolling on phone.
I’ll try to look more closely when I get back and can do a couple of tests with your version of the script next to my own. It should be doable when we pass the right code.
Worst case scenario, may have to wait until Monday, if too tired tonight.
It’s not possible to hide the PC. The only thing Lance has managed to do through XML coding is hide all the portraits on the right side of the screen and at the same time switch control to one of the companions .
For my case, that wasn’t an alternative. So instead he showed me a way of editing the stock gb_player_ud script, so that when the player clicks on the PC portrait, it immediately switches back to one of the companions instead.
It was too late for me to look at Saturday, but I believe this will work well for you … There was a key local var check I had forgotten to include on my initial post, which I had forgotten about until I checked again.
// gb_player_ud
/*
user defined events template
*/
// ChazM 9/5/06 don't have leader follow himself
// BMA-OEI 09/12/06 -- Added EVENT_PLAYER_CONTROL_CHANGED handler
// MDiekmann 8/7/07 - Modified to run a custom user defined script based on the tag if one exists
#include "ginc_companion"
#include "ginc_debug"
#include "ginc_overland"
#include "x0_i0_assoc"
#include "hench_i0_assoc"
// this includes: GetFollowDistance()
void ResetPC(object oMainPC, object oPrevious)
{
SetLocalInt(oMainPC, "STOPINFO", 1);
DelayCommand(0.1, DeleteLocalInt(oMainPC, "STOPINFO")); // REQUIRED HERE TOO
SetOwnersControlledCompanion(OBJECT_SELF, oPrevious);
}
void main()
{
int iEvent = GetUserDefinedEventNumber();
// Jug_Debug(GetName(OBJECT_SELF) + " event num " + IntToString(iEvent));
//execute custom user-defined script from local string if it exists
string sUDScript=GetLocalString(OBJECT_SELF, "ud_script");
if (sUDScript != "")
{
ExecuteScript(sUDScript, OBJECT_SELF);
}
switch (iEvent)
{
case EVENT_HEARTBEAT: // 1001
break;
case EVENT_PERCEIVE: // 1002
break;
case EVENT_END_COMBAT_ROUND: // 1003
break;
case EVENT_DIALOGUE: // 1004
break;
case EVENT_ATTACKED: // 1005
break;
case EVENT_DAMAGED: // 1006
break;
case EVENT_DISTURBED: // 1008
break;
case EVENT_SPELL_CAST_AT: // 1011
break;
case EVENT_PLAYER_CONTROL_CHANGED:
{
// MAIN PC TO TRACK VARIABLES
object oMainPC = GetFirstPC(TRUE);
//if(GetGlobalInt("chicken")) // TOO GLOBAL
//if(GetLocalInt(OBJECT_SELF, "chicken")) // BETTER TO BE TARGETTED
if(GetFirstPC() == OBJECT_SELF && GetGlobalInt("chicken")) // IF POLY ONLY EVER ON MAIN PC (& USING YOUR GLOBAL)
{
object oPrevious = GetLocalObject(oMainPC, "PREVIOUSPC");
// DELAY ALLOWS A POTENTIAL DOUBLE SWITCH WHEN "FIXING" (SHOULD ALREADY BE REMOVED, BUT FORCE HERE TOO!)
if(GetLocalInt(oMainPC, "STOPINFO")){DelayCommand(0.1, DeleteLocalInt(oMainPC, "STOPINFO")); return;}
DelayCommand(0.1, ResetPC(oMainPC, oPrevious));
}
else
{
SetLocalObject(oMainPC, "PREVIOUSPC", OBJECT_SELF);
}
break;
}
// 2052
case EVENT_TRANSFER_PARTY_LEADER:
{
if(GetIsOverlandMap(GetArea(OBJECT_SELF)))
{
PrettyDebug("gb_player_ud firing for" + GetName(OBJECT_SELF));
object oOldActor = GetLocalObject(GetModule(), "oPartyLeader");
if(GetIsPC(OBJECT_SELF) && oOldActor != OBJECT_SELF)
{
if(GetCommandable(OBJECT_SELF) && !GetIsDead(OBJECT_SELF) &&
(GetIsRosterMember(OBJECT_SELF) || GetIsOwnedByPlayer(OBJECT_SELF)) )
{
SetPartyActor(OBJECT_SELF);
}
else
SetPartyActor(oOldActor, OBJECT_SELF);
}
}
if(GetAssociateState(NW_ASC_MODE_PUPPET) == TRUE)
break;
// Jug_Debug(GetName(OBJECT_SELF) + " handle player control change");
HenchHandlePlayerControlChanged(OBJECT_SELF);
break;
}
}
}
Thanks for the reply! I might change my script, but I’ve gotten used to my version now and it seems to work quite well so…well, if I’m lazy I won’t change my script, otherwise I might.
I was not sure how all that faction checking worked for you … I mean if the player has (for example) Sabrina, Catherine and Bargoram in their party and are currently playing Bargoram, won’t the PC always default to the lowest in your checks (Sabrina in this example) as they would return TRUE as a faction member (I thought).
I.e. I think your script may only return the player back to the PC lowest in your list of PCs in your check that they have in the party. If, for example, the player has Sabrina, it will always return them to possess Sabrina and not necessarily the PC they were controlling.
But, I have not tested your script to be sure. The script I provided should always return the player to the PC they had been controlling when trying to switch. (May help to avoid any confusion if what I say above is the case.)
@andgalf Thank you very much for your answer.
Well, this is not quite what I expected / hoped for.
it’s a pity that you can’t hide it completely - nevertheless, I think that maybe I can do something - with due skill.
I’ll try. If I succeed, I’ll post, and if not, then we have nothing to lose. Thank you all.
You are totally correct that this is one of the caveats in my script at the moment, but I found it to be such a minor inconvenience that I let it be. As long as the player learns (and I think the player will learn that pretty quick) that he can’t choose his player character, all will be good. If he is stubborn and persists with choosing his own character, the game will switch back to the one at the top of my list in my script. But, again, no big deal, that’s why I, at the moment, let it be.