KOTORCommunityPatches / K1_Community_Patch

K1 Community Patch
63 stars 8 forks source link

Tatooine Eastern Dune Sea - Darth Bandon is avoidable #668

Closed JCarter426 closed 6 months ago

JCarter426 commented 2 years ago

(reported here)

It is apparently possible to avoid the Darth Bandon encounter on Tatooine by parking the party outside the Krayt dragon cave and having a party member pass through the trigger. I assume the issue is that the trigger's script checks if the entering object is the player character. It may be possible to fix this by editing the condition to be true for all party members, although that may have other side effects.

It would also be prudent to confirm if this applies to Calo as well.

DarthParametric commented 2 years ago

The same script handles both encounters (the descriptively named OnEnter tat_test for the equally descriptive newgeneric002.utt). It uses a GetIsPC(oEntering) check, along with checking global booleans and a local boolean on the trigger.

#include "k_inc_utility"

void main() {

    object oInvis1 = GetObjectByTag("tat_invis_talker", 0);
    object oInvis2 = GetObjectByTag("tat_invis_talker2", 0);
    object oEntering = GetEnteringObject();
    int nCaloState = GetGlobalBoolean("TAT_CALO_TRIGGER_SET");
    int nBandState = GetGlobalBoolean("TAT_BANDON_TRIG_SET");
    int nCaloTriggered = GetLocalBoolean(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
    int nBandTriggered = GetLocalBoolean(OBJECT_SELF, SW_PLOT_BOOLEAN_03);

    if (GetIsPC(oEntering) && nCaloState != FALSE && nCaloTriggered == FALSE)
        {
            SetGlobalBoolean("TAT_CALO_TRIGGER_SET", FALSE);

            AssignCommand(oInvis1, ActionStartConversation(OBJECT_SELF, "", FALSE, CONVERSATION_TYPE_CINEMATIC, FALSE));

            SetLocalBoolean(OBJECT_SELF, SW_PLOT_BOOLEAN_02, TRUE);
        }
        else if (GetIsPC(oEntering) && nBandState != FALSE && nBandTriggered == FALSE)
            {
                    oInvis1 = GetObjectByTag("tat_bandon_talker", 0);

                    SetGlobalBoolean("TAT_BANDON_TRIG_SET", FALSE);

                    AssignCommand(oInvis2, ActionStartConversation(OBJECT_SELF, "", FALSE, CONVERSATION_TYPE_CINEMATIC, FALSE));

                    SetLocalBoolean(OBJECT_SELF, SW_PLOT_BOOLEAN_03, TRUE);
            }
}

Edit: It should be noted that the star map scene jumps the party, so presumably this exploit is of limited usefulness in practice, and probably unlikely to occur in natural play.

The Calo and Bandon DLGs both jump the party at the start of their respective scenes, so presumably a simple switch in the above script to IsObjectPartyMember(oEntering) should prevent this.

DarthParametric commented 6 months ago

So I actually edited the wrong script. It's the trigger at the back of the cave with OnEnter k_trg_calonord2 that the exploit circumvents. That's the script that actually spawns Calo/Bandon. The trigger at the front of the cave, which is the OnEnter we edited, starts the scene with them afterwards.

Salk73 commented 6 months ago

Doesn't this mean we no longer need to replace the original script on enter _tattest for the newgeneric002 trigger?

DarthParametric commented 6 months ago

No. You could theoretically still bypass actually triggering the scene even after they have spawned by using the same trick, since both scripts only checked GetIsPC and thus won't activate with a party member as long as you aren't directly controlling them while they cross the trigger.