Unescapable Conversation

Hi,

I want to be sure that a conversation cannot be cancelled.
It can be cancelled when

  • walking away
  • perform an action
  • hitescape key
    .
    .
    .

I think I solved step 1 and 2 using this:

Conversation:

NPC “this is not a monotonous conversation” + ACTION use ADD_Immob script
YOU “this is not a monotonous conversation”
NPC “this is not a monotonous conversation”
YOU “this is not a monotonous conversation”
NPC “this is not a monotonous conversation”
YOU “this is not a monotonous conversation” + ACTION use END_Immob script

.
.
.
.
.
.
.
.
.
.

ADD_Immob script

// Put this under "Actions Taken" in the conversation editor.

void main()
{
    effect eEffect;

    // Get the PC who is in this conversation.
    object oPC = GetPCSpeaker();

    // Apply an effect.
    eEffect = SupernaturalEffect(EffectCutsceneImmobilize());
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oPC);
}

.
.
.
.
.

END_Immob script

// Put this under "Actions Taken" in the conversation editor.


#include "nw_i0_spells"


void main()
{
    // Get the PC who is in this conversation.
    object oPC = GetPCSpeaker();

    // Remove all effects of a specified type.
    RemoveSpecificEffect(EFFECT_TYPE_CUTSCENEIMMOBILIZE, oPC);
}

.
.
.
The question is: any mean to lock Escape key (excluding physically destroying the keybord key :bomb:) ??

You could restart the conversation in case it is cancelled.

Set CutsceneMode

This can be done in the conversation abort script.

More generally, the abort script can be used to ensure a tidy outcome.

You might want to accept the fact that the player wants to break the conversation. In simple cases, the abort script can be the same as the conversation end script, or the action taken script on the final line.

If conversation choices offer alternate action taken scripts, choose a default - the most likely one, perhaps, or the least favourable, if you think the player is being lazy.

In complex cases, where logical choices are made throughout the conversation, the abort script might have to analyse those flag settings to determine where the conversation was aborted, and act accordingly.

Theere is a known bug - if the conversation has only one NPC line and only one PC response (e.g. “Time to die, loser!” to which the response has a go-hostile script), neither the abort script nor the action script fire on escape. So, if you have an NPC one-liner, always ensure the PC has a choice of responses, even if they both / all do the same thing.

The only way I know to block the escape key entirely is to run the conversation in cutscene mode. Just set a local int NoAbort on the PC, then in the module OnCutsceneAbort script have

  if (GetLocalInt(oPC, "NoAbort"))
    return;

remembering to delete the NoAbort flag when the conversation ends.

In all of these cases, there’s no need for EffectCutsceneImmobilize(), because walking way or performing an action are exactly the same as escape.

1 Like

Mmh, tried some changes,

Roughly, when I replace add/remove CutImmobilize with enter/leave cutscene, the player do not have access anymore to the dialog window with NPC, and then he keeps stucked into cutscne mode.

Start cutscene mode before starting the conversation.

If conversation is started by the player clicking on the NPC, the initial conversation should do nothing but start cutscene mode and then start a different conversation. It can even be the same dialogue file if you set a flag to trigger a different conditional.

Ensure that all possible exits from the conversation cancel cutscene mode (the OnConversationEnd script is usually the convenient place to do that).

Followed your advice: much better :+1: . Now, giving a detailled debriefing.
.
.
I want this:

Inside a city, whenever the PC enters a trigger layed at city gate, a dialog appears to propose 3 choices:
to leave city way a
to leave city way b
to stay
.

Spots are:

001_TR_GATE // trigger layed at city gate
001_WP_WAY_A // waypoint placed in another Area (a road by forest)
001_WP_WAY_B // waypoint placed in another Area (a road by desert)
001_WP_BAK // waypoint placed some steps back out of 001_TR_GATE
.

001_TR_GATE has

OnEnter: 001_in_tr

void main()
{
    // Get the creature who triggered this event.
    object oPC = GetEnteringObject();

    // Only fire for (real) PCs.
    if ( !GetIsPC(oPC)  ||  GetIsDMPossessed(oPC) )
        return;

    // Cutscene functions:
    SetCutsceneMode(oPC, TRUE);

    // Have us strike up a conversation with the PC.
    ActionStartConversation(oPC, "001cv_gate", TRUE, FALSE);
}

.
OnExit: 001_out_tr

void main()
{
    // Get the creature who triggered this event.
    object oPC = GetExitingObject();

    // Only fire for (real) PCs.
    if ( !GetIsPC(oPC)  ||  GetIsDMPossessed(oPC) )
        return;

    // Cutscene functions:
    SetCutsceneMode(oPC, FALSE);
}

.
.

The trigger fires the conversation 001cv_gate

Leaving city?
Yes, following north road (way A) → Action 001_way_a
Yes, following easth road (way B) → Action 001_way_b
No, staying city. → Action 001_bak

.
001_way_a

void main()
{
    object oParty;
    object oTarget;

    // Get the PC who is in this conversation.
    object oPC = GetPCSpeaker();

    // Find the location to which to teleport.
    oTarget = GetWaypointByTag("001_WP_WAY_A");

    // Teleport the PC's party.
    // Loop through the PC's party.
    oParty = GetFirstFactionMember(oPC, FALSE);
    while ( oParty != OBJECT_INVALID )
    {
        AssignCommand(oParty, ClearAllActions());
        AssignCommand(oParty, JumpToObject(oTarget));

        // Update the loop.
        oParty = GetNextFactionMember(oPC, FALSE);
    }
}

.

001_way_b

void main()
{
    object oParty;
    object oTarget;

    // Get the PC who is in this conversation.
    object oPC = GetPCSpeaker();

    // Find the location to which to teleport.
    oTarget = GetWaypointByTag("001_WP_WAY_B");

    // Teleport the PC's party.
    // Loop through the PC's party.
    oParty = GetFirstFactionMember(oPC, FALSE);
    while ( oParty != OBJECT_INVALID )
    {
        AssignCommand(oParty, ClearAllActions());
        AssignCommand(oParty, JumpToObject(oTarget));

        // Update the loop.
        oParty = GetNextFactionMember(oPC, FALSE);
    }
}

.

001_bak

void main()
{
    // Get the PC who is in this conversation.
    object oPC = GetPCSpeaker();

    // Have the PC perform a sequence of actions.
    AssignCommand(oPC, ActionMoveToObject(GetNearestObjectByTag("001_WP_BAK")));
}

So any choice results includes to exit the trigger and to exit the trigger ends Cutscene Mode.

BUT
.

A) I tested, conversation in cutscene mode works and I cannot cancel it.
I still NOT yet USED this:

if (GetLocalInt(oPC, "NoAbort"))
    return;

But I see that ESCAPE does not work anyway, what may explain that?
.
.

B) Should I be more cautious and should I add

CutsceneMode(oPC, FALSE);

into the choice scripts too?
(001_way_a, 001_way_b, 001_bak)
.
.

PS:
Of course, I do not have the coding level and I always have to use:
LS Script Generator, v.TK.0

It’s just about choosing a path out of an area? I don’t understand, why there must be an unabortable dialog, cutscene etc. If the the player chooses a, jump to a, if he chooses b, jump to b, if he chooses to stay or aborts the dialogue, just do nothing. If the player enters the trigger again, just show the dialogue again.

The OnCutsceneAbort event does nothing, by default. The NoAbort logic is only necessary if you have other cutscenes that the player is allowed to abort (which tends to be the case, in larger modules).

If jumping to a new area breaks cutscene mode, I wouldn’t bother.

Good point.

Big thanks for your advices :slight_smile:
I may understand why you wonder about such a botherness about a simple Area transition.

Hope that I will find the correct english words to explain that:

I intend to fade the closed box effet of areas in order to gain a better opened surrounding feeling.
To reach that I do not want the player to visualize the edge of the area. So I measure when such a border may be in sight and I drop an unclickable area transition before that line of sight.
With that, I will keep placing buildings, people, trees and other scenery element over the transition trigger. The point is that I do not want the player being able to reach this “backstage decor” using any abort way.

For example 2 city districts, A and B
When leaving from A, the player will see a little part of B before transiting and when entering B, he will have a little part of A behind him. In this case, The Area transition trigger will only teleport when Entered, nothing else, no cutscene, no conversation.

The case of the city gate is different because the city is left for another kind of surroundings but, I do not want the player to pass over the trigger, because he would see an area edge.
.
.
Rereading my post, I’m not sure you it will make you catch the idea I have :crazy_face: :crazy_face: :crazy_face:

If I understand correctly, you’re saying that you’re using a trigger to start a conversation which then asks the player where they wish to go. But if the player aborts the conversation, then they could walk past the trigger into an area you don’t want them to go. Is this correct?

All you need to do is to have a script which runs when the conversation is aborted, and have that script make the player character jump to a waypoint which is outside of the trigger area (in front of the gate).

Yes Melkior, this is what I needed :slight_smile: