Hi all,
a problem has come up in my campaign and 3 people reported that they are stuck because of it and I need some help solving it.
The facts:
Conversation trigger doesn’t fire on ongoing game
Same trigger fires if area is loaded from toolset
Same trigger never malfunctioned before.
The script which is used is this
// 'dialog_tr'
//
/*******************************************************************************
Andy for Return of the Exile
22.1.2016
kevL rework
28.1.2016
To be used by a trigger's onEnter event.
Starts a dialog. See TRIGGER VARIABLES below.
Works with both SoZ-style.
Works with an i-point placeable as owner as well.
-------------
Additions
-------------
30.1.2016 : Added a party face target. Note that this adresses the start of the dialogue
If the party moves or the NPC moves, we still need to adjust the facing using the ga_party_face
30.1.2016 : Added a bPCTalk option. For cutscenes that NEED to happen,
but where the NPC only needs to talk to the PC. Instead of the idiotic warp,
the main PC stays where he is but control switches to him.
4.2.2016 : Added a method for required creatures in order to start the dialogue. Good to have
4.2.2016 : Commented out the required creatures because of too much complexity. Perhaps in the future another trigger could
be made for it, and all these function in a library.
If this is ever added, remember to change the
if (!GetLocalInt(oTrig, "bCondition")) with
if (!GetLocalInt(oTrig, "bCondition") && checkRequiredTalkers(GetLocalString(oTrig, "sTalkers")))
-------------
TODO
-------------
Add a bForce option that makes party/oSpeaker conversable.
Add an option to use fade-in/fade-outs.
Add an option to delay the conversation start.
Possibly implement a heartbeat like CreateIPSpeaker() uses.
Add an option to disable cutscene bars.
Add a variable to check for item
-------------
TRIGGER VARIABLES
---------
bCondition - Default 0. Set it to 1 so that the trigger won't fire if
we go inside. If it needs to fire further in the game,
set a local int on the trigger called bCondition = 0.
sQuestCond - Default "". The tag of the quest if a QuestCondition is
needed.
iQuestCond - Default 0. The ID of the quest if a QuestCondition is
needed.
sSpeaker - Default "". The tag of the creature to be speaking to the
party.
sConvo - Default "". Name of the conversation file.
bDestroySelf - Default 0. Set to 1 if the trigger should get destroyed
after it's done its job.
bParty - Default 0. Set to 1 if the conversation is an internal
party dialog. Checks if the companions needed (speaker) is in party.
bPCTalk - Default 0. Set to 1 if Speaker is supposed to talk to the PC only.
Note: Leave bParty default FALSE.
sTalkers - Default "". A list of tags for required participants excluding PC and Speaker (comma-separated, no spaces).
This is not used at the moment.
*******************************************************************************/
//__________________
// ** PROTOTYPES ***
// Checks if target can talk.
int getConversable(object oTarget, int bFaction = FALSE);
// Checks if an effect prevents dialog.
int hasEffectSpeechless(object oTarget);
// Makes party face the speaker
void PartyFace(object oFacer, object oFaced);
// Checks if required talkers are present and conversable.
//int checkRequiredTalkers(string sTalkers);
//____________
// ** MAIN ***
void main()
{
object oTrig = OBJECT_SELF;
if (!GetLocalInt(oTrig, "bCondition"))
{
object oPlayer = GetEnteringObject();
//SendMessageToPC(oPlayer, "Script has fired upon entering the trigger");
if (GetIsPC(oPlayer) && getConversable(oPlayer, TRUE))
{
string sQuestCond = GetLocalString(oTrig, "sQuestCond");
if (sQuestCond == ""
|| GetJournalEntry(sQuestCond, GetOwnedCharacter(oPlayer)) == GetLocalInt(oTrig, "iQuestCond"))
{
object oSpeaker = GetNearestObjectByTag(GetLocalString(oTrig, "sSpeaker"));
if (GetIsObjectValid(oSpeaker))
{
int bParty = GetLocalInt(oTrig, "bParty");
if (bParty || getConversable(oSpeaker))
{
if (bParty || GetLocalInt(oTrig, "bPCTalk"))
oPlayer = SetOwnersControlledCompanion(oPlayer);
if (!bParty || GetFactionEqual(oPlayer, oSpeaker))
{
AssignCommand(oSpeaker, ClearAllActions());
AssignCommand(oPlayer, ClearAllActions());
PartyFace(oPlayer, oSpeaker);
DelayCommand(0.25f, AssignCommand(oSpeaker,
ActionStartConversation(
oPlayer,
GetLocalString(oTrig, "sConvo"),
FALSE, FALSE, TRUE, FALSE)));
if (GetLocalInt(oTrig, "bDestroySelf"))
DelayCommand(3.0f, DestroyObject(oTrig));
}
}
}
}
}
}
}
//_________________
// ** FUNCTIONS ***
// Set the facing of the party to the speaker.
// oFacer - the PC or companion
// oFaced - the speaker
// It happens by default. No need for any trigger variable here.
void PartyFace(object oFacer, object oFaced)
{
object oFM = oFacer;
vector vTarget = GetPosition(oFaced);
oFacer = GetFirstFactionMember(oFM, FALSE);
while(GetIsObjectValid(oFacer))
{
AssignCommand(oFacer, ActionDoCommand(SetFacingPoint(vTarget, FALSE)));
AssignCommand(oFacer, ActionWait(0.5f));
oFacer = GetNextFactionMember(oFM, FALSE);
}
}
// Checks if target can talk.
// oTarget - creature to check
// bFaction - true to check target's faction (default FALSE)
int getConversable(object oTarget, int bFaction = FALSE)
{
if (bFaction)
{
object oFaction = GetFirstFactionMember(oTarget, FALSE);
while (GetIsObjectValid(oFaction))
{
if (GetIsDead(oFaction)
|| GetIsInCombat(oFaction)
|| IsInConversation(oFaction)
|| hasEffectSpeechless(oFaction))
{
return FALSE;
}
oFaction = GetNextFactionMember(oTarget, FALSE);
}
}
else if (GetIsDead(oTarget)
|| GetIsInCombat(oTarget)
|| IsInConversation(oTarget)
|| hasEffectSpeechless(oTarget))
{
return FALSE;
}
return TRUE;
}
// Checks if required talkers are present and conversable.
// sTalkers - a comma-separated list of creature-tags (spaces *not* allowed)
/*int checkRequiredTalkers(string sTalkers)
{
string sTalker;
object oTalker;
int iSeparator = 0;
while (GetStringLength(sTalkers) > 0 && iSeparator != -1)
{
iSeparator = FindSubString(sTalkers, ",");
if (iSeparator == -1)
sTalker = sTalkers;
else
sTalker = GetStringLeft(sTalkers, iSeparator);
oTalker = GetNearestObjectByTag(sTalker);
if (!GetIsObjectValid(oTalker) || !getConversable(oTalker))
return FALSE;
sTalkers = GetStringRight(sTalkers, GetStringLength(sTalkers) - iSeparator - 1);
}
return TRUE;
}*/
// Checks if an effect prevents dialog.
// oTarget - creature to check
int hasEffectSpeechless(object oTarget)
{
int iEffect;
effect eEffect = GetFirstEffect(oTarget);
while (GetIsEffectValid(eEffect))
{
iEffect = GetEffectType(eEffect);
if ( iEffect == EFFECT_TYPE_CONFUSED
|| iEffect == EFFECT_TYPE_CUTSCENE_PARALYZE
|| iEffect == EFFECT_TYPE_CUTSCENEGHOST
// || iEffect == EFFECT_TYPE_CUTSCENEIMMOBILIZE
|| iEffect == EFFECT_TYPE_DAZED
|| iEffect == EFFECT_TYPE_DEAF
|| iEffect == EFFECT_TYPE_DOMINATED
// || iEffect == EFFECT_TYPE_ENTANGLE
// || iEffect == EFFECT_TYPE_FRIGHTENED
// || iEffect == EFFECT_TYPE_GREATERINVISIBILITY
|| iEffect == EFFECT_TYPE_INSANE
// || iEffect == EFFECT_TYPE_INVISIBILITY
// || iEffect == EFFECT_TYPE_JARRING
|| iEffect == EFFECT_TYPE_MESMERIZE
|| iEffect == EFFECT_TYPE_PARALYZE
|| iEffect == EFFECT_TYPE_PETRIFY
// || iEffect == EFFECT_TYPE_POLYMORPH
|| iEffect == EFFECT_TYPE_SILENCE
|| iEffect == EFFECT_TYPE_SLEEP
|| iEffect == EFFECT_TYPE_STUNNED)
// || iEffect == EFFECT_TYPE_TURNED
{
return TRUE;
}
eEffect = GetNextEffect(oTarget);
}
return FALSE;
}
The same script is used throughout the whole campaign to initiate convos and it only fails in this area, and only recently. People have finished the game by actually having the conversation needed.
The parameters of the trigger have been extensively checked, and not just on my game instance but also on the uploaded instance and are correct… in other words, tags for speakers etc match.
I’ve tried initiating the conversation for the players, so that they can continue playing, via console.
rs ga_start_convo(“trial_enc_owner”, “enc_trial_begin”, 0, 0, 1, 0)
rs ga_conversation_self(“enc_trial_begin”)
and
rs debug_script
for this script
#include "ginc_ipspeaker"
void main()
{
CreateIPSpeaker("trial_enc_owner", "enc_trial_begin", GetLocation(GetFirstPC()), 0.5);
}
have all failed.
The conversation does not have any “Once only” or conditions. There are action scripts attached but things like
ga_move
ga_global_int
etc.
In other words, nothing that should break the convo or cause it to fail beginning.
At this point I am thinking of jumping the players who have reported it to a different area in order to bypass the issue, but this is not a general solution. Something is weird here. If anyone who has downloaded my campaign and feels like looking at the area for reference the details are:
module name: 14_Randomencounter
convo name: enc_trial begin
area name: enc_trial_begin
Thanks a lot for any possible help .