Aller au contenu

Photo

Running a cutscene in a new area


  • Veuillez vous connecter pour répondre
11 réponses à ce sujet

#1
DahliaLynn

DahliaLynn
  • Members
  • 1 387 messages
Currently I use a script to run a cutscene. I would like the cutscene to be shown using a custom area.
I have researched this and came to the conclusion that I must jump the player to the new area before th cutscene plays.

My current relevant script is as follows:

        {
     case ALISTAIR_WEDDING_QUEEN:
                {              
                    EquipItem(oPC, oChestArmour);

                    CS_LoadCutscene(R"hnf_wedding.cut");

                    break;
                }

        }
    }

I believe I need to insert the following script when this case/plot is met (please let me know if I need to show more of this script if that will help.)

int DoAreaTransition(

string sArea,
string sWaypointTag

);




where the name of the new area would be "wedding_area_2.are"
and the waypoint (I hope it repositions in the cutscene though!) "wp_mapnote_exit"

Am I correct in assuming that this would be the place I need to insert these lines? and if so, how do I do it while being syntactically correct?

Modifié par DahliaLynn, 07 septembre 2010 - 05:03 .


#2
Sunjammer

Sunjammer
  • Members
  • 925 messages
You would have to jump the party to the new area and then in the new area's script use the area's preload exit event to load and run the cutscene.

The syntax for the transition is:

DoAreaTransition("wedding_area_2", "wp_mapnote_exit");


#3
DahliaLynn

DahliaLynn
  • Members
  • 1 387 messages
Thank you for that. I have inserted that line right before the Equipitem command, It compiled correctly, but the scene still uses the original post coronation landsmeet chamber area (and all of it's unneeded trimmings.)
this occurs at end of game by the way.

The situation is as follows: End of game: Speak to guard at exit.
If conditions are met, cutscene is called from the dialogue through script.

If I understand you correctly, what I need to do is replace the cutscene call from the script with jump to new area, then create a new script, attach it to the new area, having it preload the new area with the cutscene?

And if the above is true, does this mean that the player will view a glimpse of the new area before firing the cutscene?

Edit: Lastly, would you know what would be the script I need to use to preload the new area with to call the cutscene?

Modifié par DahliaLynn, 07 septembre 2010 - 06:55 .


#4
Sunjammer

Sunjammer
  • Members
  • 925 messages

DahliaLynn wrote...

Thank you for that. I have inserted that line right before the Equipitem command, It compiled correctly, but the scene still uses the original post coronation landsmeet chamber area (and all of it's unneeded trimmings.)
this occurs at end of game by the way.

The situation is as follows: End of game: Speak to guard at exit.
If conditions are met, cutscene is called from the dialogue through script.

If I understand you correctly, what I need to do is replace the cutscene call from the script with jump to new area, then create a new script, attach it to the new area, having it preload the new area with the cutscene?

And if the above is true, does this mean that the player will view a glimpse of the new area before firing the cutscene?

Edit: Lastly, would you know what would be the script I need to use to preload the new area with to call the cutscene?

I would put the DoAreaTransition after the EquipItem - I've not tested it but I don't really see it surviving the transition.

If I'm following what you are trying to do then you are probably going to have to to override the epi100cr_guard_1 conversation and epipt_main plot and script: when you speak to the guard at the end of the game he says "Right. I'll take you there now. Follow me." The dialogue ends and it sets the EPI_JUMP_TO_SLIDE_SHOW plot flag. This triggers the correpsonding case statement that looks like this:

            case EPI_JUMP_TO_SLIDE_SHOW:
            {
                string sArea = GetTag(GetArea(OBJECT_SELF));
                // Cancel all ambient sounds.
                // If Post Coronation
                if (sArea == EPI_AR_POST_CORONATION)
                    AudioTriggerPlotEvent(EPI_AUDIO_POSTCORONATION_AMB_OFF);
                else
                // If Funeral
                    AudioTriggerPlotEvent(EPI_AUDIO_FUNERAL_AMB_OFF);

                BeginSlideshow(TALK_EPI_SLIDESHOW);
                break;
            }
Which is what you are still seeing in game I suspect.

I've never messed witht the Single Player game but I believe the easiest way to prevent/postpone this default ending playing at this point is to add a new main plot flag to the epipt_main plot (for example called EPI_JUMP_TO_WEDDDING_2) and have the final node in the epi100cr_guard_1 conversation set this new flag instead of EPI_JUMP_TO_SLIDE_SHOW. Then add a new case statement into the epipt_main script along the lines of:

            case EPI_JUMP_TO_WEDDDING_2:
            {
                EquipItem(...
                DoAreaTransition(...
                break;
            }

Then you need to create a new area script and attach it to your area's Script property.

The player won't see the area before the cutscene starts but to do this you'll actually want to use the EVENT_TYPE_AREALOAD_SPECIAL event (that will teach me to rely on my ailing memory).

The following is a rough outline of a (very) basic area script to play a cutscene on entry to an area and then plays the normal epilogue slide show:

#include "2da_constants_h"
#include "events_h"
#include "utility_h"

#include "plt_epipt_main"

void main()
{
    int nEventHandled = FALSE;

    // deconstruct event
    event evCurrent = GetCurrentEvent();
    int nEventType = GetEventType(evCurrent);

    // common variables
    object oHero = GetHero();

    //---------------------------------------------------------------------------
    // Handle Events
    //---------------------------------------------------------------------------

    switch(nEventType)
    {
        case EVENT_TYPE_AREALOAD_SPECIAL:
        {
            CS_LoadCutscene(R"yourcutscene.cut", PLT_EPIPT_MAIN, EPI_JUMP_TO_SLIDE_SHOW);
            break;
        }
    }

    //---------------------------------------------------------------------------
    // Unhandled Events
    //---------------------------------------------------------------------------

    if(!nEventHandled)
    {
        HandleEvent(evCurrent, RESOURCE_SCRIPT_AREA_CORE);
    }
}

If you don't want the slide show then replace EPI_JUMP_TO_SLIDE_SHOW with EPI_JUMP_TO_CREDITS.

Modifié par Sunjammer, 07 septembre 2010 - 08:38 .


#5
Sunjammer

Sunjammer
  • Members
  • 925 messages
Sorry I forgot I should probably mention adding conditions as you mentioned them ...

In the above your new case statement should include some logic to determine whether or not you should jump to the new wedding area so it should really be something like:

            case EPI_JUMP_TO_WEDDDING_2:
            {
                if(-insert-your-conditions-here-)
                {
                    EquipItem(...);
                    DoAreaTransition(...);
                }
                else
                {
                    // jump to slideshow
                    WR_SetPlotFlag(PLT_EPIPT_MAIN, EPI_JUMP_TO_SLIDE_SHOW, TRUE);
                }
                break;
            }

Having the right logic in
-insert-your-conditions-here-
will prevent unnecessary trips to the wedding when, for example, participants are dead.

Modifié par Sunjammer, 07 septembre 2010 - 09:21 .


#6
DahliaLynn

DahliaLynn
  • Members
  • 1 387 messages
Thank you so much. I am going to try this. I might end up having the "dead people" problem showing up, since the original script with the original landsmeet area took care of that issue and I will no longer be using that script in this case. But first I will do this.


#7
DahliaLynn

DahliaLynn
  • Members
  • 1 387 messages
Everything seems to be working, ---only problem is, nothing has changed. The cutscene is still loading using the current landsmeet chamber :( Any ideas why it's still firing in the same area?

Edit: I was thinking, the original area was not connected to any area list. The new one isn't either. Do I need to create an area list for this?

Here is the edited first script: (with an original plot and flag created previuosly)
============================================================

#include "plt_alistair_scenes_main"
#include "log_h"
#include "utility_h"
#include "wrappers_h"
#include "plot_h"
#include "plt_genpt_leliana_main"
#include "plt_genpt_app_leliana"
#include "plt_genpt_app_alistair"
#include "plt_genpt_app_zevran"
#include "plt_genpt_app_morrigan"
#include "plt_cod_cha_leliana"
#include "plt_mnp000pt_generic"
#include "plt_gen00pt_party"
#include "plt_gen00pt_party_gilmore"
#include "plt_gen00pt_class_race_gend"
#include "plt_gen00pt_backgrounds"
#include "plt_ntb000pt_main"
#include "den_lc_constants_h"
#include "ran_constants_h"
#include "plt_genpt_leliana_events"
#include "plt_mnp000pt_autoss_main2"
#include "plt_mnp00pt_ssf_arl_eamon"
#include "plt_ntb000pt_main"
#include "plt_orzpt_anvil"
#include "plt_denpt_rescue_the_queen"
#include "plt_mnp000pt_main_lothering"
#include "plt_denpt_main"
#include "plt_denpt_alistair"
#include "plt_epipt_main"
#include "plt_test_cutscene_plot"




int StartingConditional()
{
    event   eParms              = GetCurrentEvent();            // Contains all input parameters
    int     nType               = GetEventType(eParms);         // GET or SET call
    int     i;                                                  // Counter
    string  strPlot             = GetEventString(eParms, 0);    // Plot GUID
    int     nFlag               = GetEventInteger(eParms, 1);   // The bit flag # being affected
    object  oParty              = GetEventCreator(eParms);      // The owner of the plot table for this script
    object  oConversationOwner  = GetEventObject(eParms, 0);    // Owner on the conversation, if any
    int     nResult             = FALSE;                        // used to return value for DEFINED GET events
    object  oPC                 = GetHero();
    object oChestArmour = UT_AddItemToInventory(R"wedding_dress.uti");

    plot_GlobalPlotHandler(eParms); // any global plot operations, including debug info
    if(nType == EVENT_TYPE_SET_PLOT) // actions -> normal flags only
    {
        int nValue      = GetEventInteger(eParms, 2);     // On SET call, the value about to be written (on a normal SET that should be '1', and on a 'clear' it should be '0')
        int nOldValue   = GetEventInteger(eParms, 3);     // On SET call, the current flag value (can be either 1 or 0 regardless if it's a set or clear event)

        // IMPORTANT: The flag value on a SET event is set only AFTER this script finishes running!
        switch(nFlag)
        {


     case ALISTAIR_WEDDING_QUEEN:
                {             

                    EquipItem(oPC, oChestArmour);

                    DoAreaTransition("wedding_area_2.are", "wp_mapnote_exit");
                                  
                    break;
                }


        }
    }




  else // EVENT_TYPE_GET_PLOT -> defined conditions only

    {
       switch(nFlag)
       {
       case PC_QUEEN_LOVE:

               {
                    if (WR_GetPlotFlag(PLT_DENPT_ALISTAIR,DEN_ALISTAIR_MARRYING_PLAYER) && !WR_GetPlotFlag(PLT_EPIPT_MAIN,EPI_PC_MARRY_ALISTAIR_NO_LOVE))
                        nResult=TRUE;
                    else
                        nResult=FALSE;
                    break;
               }
    }
    }


    return nResult;
}

New Script attached to area:
==================================================================
#include "plt_alistair_scenes_main"             
#include "2da_constants_h"
#include "events_h"
#include "utility_h"

#include "plt_epipt_main"


void main()
{
    int nEventHandled = FALSE;

    // deconstruct event
    event evCurrent = GetCurrentEvent();
    int nEventType = GetEventType(evCurrent);

    // common variables
    object oHero = GetHero();

    //---------------------------------------------------------------------------
    // Handle Events
    //---------------------------------------------------------------------------

    switch(nEventType)
    {
        case EVENT_TYPE_AREALOAD_SPECIAL:
        {
            CS_LoadCutscene(R"hnf_wedding.cut");
            break;
        }
    }

    //---------------------------------------------------------------------------
    // Unhandled Events
    //---------------------------------------------------------------------------

    if(!nEventHandled)
    {
        HandleEvent(evCurrent, RESOURCE_SCRIPT_AREA_CORE);
    }
}

And a final script attached to first cutscene where I inserted a general cutscene for testing :
========================================================================

#include "plt_alistair_scenes_main"
#include "log_h"
#include "utility_h"
#include "wrappers_h"
#include "plot_h"
#include "plt_genpt_app_alistair"
#include "plt_mnp000pt_generic"
#include "plt_gen00pt_backgrounds"
#include "plt_ntb000pt_main"
#include "den_lc_constants_h"
#include "ran_constants_h"
#include "plt_mnp000pt_autoss_main2"
#include "plt_denpt_main"
#include "plt_denpt_alistair"
#include "plt_epipt_main"


void main()
{
    CS_LoadCutscene(R"alistair_sex_hf.cut",PLT_EPIPT_MAIN, EPI_JUMP_TO_SLIDE_SHOW);
}

Modifié par DahliaLynn, 08 septembre 2010 - 12:07 .


#8
Sunjammer

Sunjammer
  • Members
  • 925 messages
There's no need, that I'm aware of, to add the area to an arealist. Adding it to the correct arealist would speed up the transition but it is not essential.

One thing I noticed:

DoAreaTransition("wedding_area_2.are", "wp_mapnote_exit");

should be:
DoAreaTransition("wedding_area_2", "wp_mapnote_exit");

However if a cutscene is firing in the original area it sounds like the above isn't overriding properly as the cutscene should only fire when you enter the new area.

Modifié par Sunjammer, 08 septembre 2010 - 08:44 .


#9
DahliaLynn

DahliaLynn
  • Members
  • 1 387 messages
A very interesting thing occurred when making this last change you suggested. Now, after the dialogue ends, player remains in current area, wearing a new dress, with "items received" . Meaning, the equip armor worked, but the transport function did not, *and* the cutscene has not fired, i.e. player remains in same position.

Now, since the area transition could not be made successfuly, the cutscene could not be called.
There are still inconsistencies which I don't understand though. (how could the cutscene have  played if it was only called from the new area ?)

Would it be possible that the *First area* the original Chamber that I am leaving, is attached to a script which might not allow this to happen?

I see two possible problems.

1. What do I need to do to transport PC to new area? am I doing everything correctly?
2. Origin area script might conflict

Here is the original Area script attachment:
//==============================================================================
/*

Coronation Post Ceremony
-> Epilogue Coronation Post Ceremony (Plays when area loads)

*/
//------------------------------------------------------------------------------
// Created By: Mark Barazzuol
// Created On: May 27, 2008
//==============================================================================

#include "epi_attendees_h"

const string SHL_MODULE_ID = "DAO_PRC_CP_2";
void main()
{

//--------------------------------------------------------------------------
// Initialization
//--------------------------------------------------------------------------

// Constants


// Load Event Variables
event evEvent = GetCurrentEvent(); // Event
int nEventType = GetEventType(evEvent); // Event Type
object oEventCreator = GetEventCreator(evEvent); // Event Creator

// Standard Stuff
object oPC = GetHero();
object oParty = GetParty( oPC );
int bEventHandled = FALSE;


//--------------------------------------------------------------------------
// Area Events
//--------------------------------------------------------------------------

switch ( nEventType )
{

case EVENT_TYPE_AREALOAD_POSTLOADEXIT:
{

//------------------------------------------------------------------
// EVENT_TYPE_AREALOAD_POSTLOADEXIT:
// Sent by: The engine
// When: fires at the same time that the load screen is going away,
// and can be used for things that you want to make sure the player
// sees.
//------------------------------------------------------------------

int bAreaLoadedOnce;

//------------------------------------------------------------------

bAreaLoadedOnce = GetLocalInt( OBJECT_SELF, AREA_COUNTER_1 );

//------------------------------------------------------------------

// These are called from epi_attendees_h
// Populates the room with the proper NPCs
SetKingAndQueen();
SetPartyMembersAttending();
SetOriginMembersAttending();

// First time initial coronation scene plays
if( !bAreaLoadedOnce )
{
object oShale = UT_GetNearestObjectByTag(oPC, EPI_CR_SHALE);
if (GetPRCEnabled(SHL_MODULE_ID))
{
SetAppearanceType(oShale, 10100);
}
SetLocalInt( OBJECT_SELF, AREA_COUNTER_1, TRUE );
UT_Talk( oPC, oPC, TALK_EPI_POST_CORONATION_START);
}

break;

}


case EVENT_TYPE_ENTER:
{

//------------------------------------------------------------------
// EVENT_TYPE_ENTER:
// Sent by: The engine
// When: A creature enters the area.
//------------------------------------------------------------------

break;

}


case EVENT_TYPE_EXIT:
{

//------------------------------------------------------------------
// EVENT_TYPE_EXIT:
// Sent by: The engine
// When: A creature exits the area.
//------------------------------------------------------------------

break;

}

}

//--------------------------------------------------------------------------
// Pass any unhandled events to area_core
//--------------------------------------------------------------------------

if ( !bEventHandled )
HandleEvent( evEvent, AREA_CORE );

Modifié par DahliaLynn, 08 septembre 2010 - 12:45 .


#10
Sunjammer

Sunjammer
  • Members
  • 925 messages
That's a step forward. At least now your revised script is now overriding the original. Hopefully all you need to do now is ensure that the new area and script are in an appropriate override directory so they can be seen by the Single Player campaign and that the new area's tag and waypoint's tags correct and unique.

Note an area's tag is the same as it's Resource Name property (i.e. the blueprint withou the .are extension).

#11
DahliaLynn

DahliaLynn
  • Members
  • 1 387 messages
I tried renaming the waypoint to make it unique, and made sure the area call had no extension but the same thing is still happening. Is there anything you see here that I might be doing wrong?

This is how I have things set up:

Posted Image

Posted Image

Posted Image

Posted Image

Modifié par DahliaLynn, 08 septembre 2010 - 06:47 .


#12
DahliaLynn

DahliaLynn
  • Members
  • 1 387 messages
Problem solved. New module settings were incorrect therefore export was incorrect.