Help - Search - Members - Calendar
Full Version: The Pain of Coding Cutscenes
The Black Wyrm's Lair - Forums > Mod development resources & discussion > Modder's Workshop
Amazor'dra
In the Neht mod there is now a cutscene where an Enforcer (insanely powerful undead that hunts other undead) makes a lich die in a very painful and flashy way.

The Enforcer gives his mightier-than-thou speech and it fires off like it should, until the very end when the cutscene is supposed to start. The game goes into cutscene mode... and does nothing. I have no idea why it is not doing anything, except that is probably something simple and/or moronic that I missed.

The Enforcer's Banter:

CODE
CHAIN IF ~Global("Enforcer","LOCALS",1)~ THEN SK#ENF 0ENF
~Well now, gaining access to your little hideout turned out far easier than I thought it would be, lich. Having to hunt you down and kill you in pieces all the way from Calimport had been fun up till now. A pity only the skull of you is left.~ DO ~SetGlobal("Enforcer","LOCALS",2)~
== SK#ENF ~Are these allies of yours, Aeldredus? Not that their help would do you much good against me.~
== SK#LICH ~Hardly.~
== SK#ALGOL ~Soooo sorry, Master!~
== SK#LICH ~I'm sure you are, as sorry as anyone whose main concern is preserving their own rotting skin.~
== SK#NEHTJ ~<CHARNAME>... with an Enforcer here, we should leave immediately.~
END
++ ~I have no idea what is going on.~ EXTERN ~SK#ENF~ 1ENF
++ ~Why? Things are just beginning to get interesting.~ EXTERN ~SK#ENF~ 2ENF
++ ~We came here to put an end to the slave trade, not run away at the first sign of trouble.~ EXTERN ~SK#ENF~ 3ENF
++ ~I agree, leaving seems to be a good idea.~ EXTERN ~SK#ENF~ 4ENF
++ ~We should help that lich.~ EXTERN ~SK#ENF~ 5ENF


APPEND SK#ENF
IF ~~ THEN BEGIN 1ENF
SAY ~Just as well, I might have to kill you too. Fleshies knowing too much about the undead could cause problems for my masters. Let me deal with the lich, then you and I can spend as much time as we want together.~
IF ~~ THEN DO ~SetGlobal("Enforcer","LOCALS",2)
ClearAllActions()
StartCutSceneMode()
StartCutScene("SK#CUT1")~ EXIT
END

IF ~~ THEN BEGIN 2ENF
SAY ~That's the spirit! I knew I would like you. Ever thought much about what you'd do once you died? No? Well, I suppose soon we'll find out.~
IF ~~ THEN DO ~SetGlobal("Enforcer","LOCALS",2)
ClearAllActions()
StartCutSceneMode()
StartCutScene("SK#CUT1")~ EXIT
END

IF ~~ THEN BEGIN 3ENF
SAY ~Only a fool doesn't run away from what can kill him, but I digress. Give me a moment and then we'll spend some more quality time together.~
IF ~~ THEN DO ~SetGlobal("Enforcer","LOCALS",2)
ClearAllActions()
StartCutSceneMode()
StartCutScene("SK#CUT1")~ EXIT
END

IF ~~ THEN BEGIN 4ENF
SAY ~It is now far too late for that, little fleshling. You will now stay, stay and realize just how deep the hole you have dug yourself into.~
IF ~~ THEN DO ~SetGlobal("Enforcer","LOCALS",2)
ClearAllActions()
StartCutSceneMode()
StartCutScene("SK#CUT1")~ EXIT
END

IF ~~ THEN BEGIN 5ENF
SAY ~No, you will do nothing, and by doing nothing you'll live just a few moments longer.~
IF ~~ THEN DO ~SetGlobal("Enforcer","LOCALS",2)
ClearAllActions()
StartCutSceneMode()
StartCutScene("SK#CUT1")~ EXIT
END
END


The Cutscene:

CODE
IF
    True()
THEN
    RESPONSE #100
        CutSceneId("SK#CUT1")
Wait(1)
ActionOverride("SK#ENF",ForceSpellPoint([608.304],CUTSCENE_METEOR_SWARM))
Wait(3)
ActionOverride("SK#ENF",ForceSpellPoint([608.304],FLASHY_DEATH_3))
Wait(1)
DisplayStringWait("SK#LICH",~I am sorry, my wife... for being unable to give you the child you wanted.~)
        ActionOverride("SK#LICH",Kill(Myself))
        Wait(2)
EndCutSceneMode()
ActionOverride("SK#ENF",StartDialogueNoSet(Player1))
END


Any help in fixing this will be very much appreciated. cool.gif
Sikret
QUOTE(Amazor'dra @ May 13 2007, 03:18 PM) *

CODE
IF
    True()
THEN
    RESPONSE #100
        CutSceneId("SK#CUT1")


Any help in fixing this will be very much appreciated. cool.gif


Change CutSceneId("SK#CUT1") line to CutSceneId("SK#ENF") and see if it helps.

Amazor'dra
That does indeed help, a little. Now the cutscene gets as far as finishing the first forcespell before doing nothing again. I'm guessing that since ENF isn't far enough away from the cutscene meteor swarm to keep from getting hit, that is interrupting the script, despite it all being action overrided. ph34r.gif
Cuv
Hi Amazor'dra

Remember that CutsceneID is the death variable of the creature running the cutscene. Sikret pointed out that change, but not why wink.gif

I think the there are a few reasons why the script isnt finishing:

-You have the meteor swarm and a flashy death at spellpoint instead of hitting a specified creature.
-You are using ActionOverride when it is unnecessary, just forcespell will do, the cutscene ID should be SK#ENF.
-You are having SK#LICH display a headstring when he may already be dead.
-Double-check your 'waits', they may not be long enough to finish the actions.
-Also, you may want to create a seperate cutscene for the Dialog starting.

I have to run, but will check back tomorrow and see how it is going for you. I probably haven't been terribly helpful sad.gif

Cuv
cmorgan
Cuv has some god stuff...

SK#CUT1.BAF gets compiled, and assigned as the cutscene, but the ID is the scriptrunner...
and
DisplayStringWait(O:Object*,I:StrRef*)
I actually have not seen this used in a mod (if someone could provide reference, I would be appreciative smile.gif )

If you try this as
DisplayStringHead(O:Object*,I:StrRef*) on a live .cre you might be happier, as you already have Wait(#)s.

ActionOverride("SK#ENF" means you are asking the DV "SK#ENF" to do something, so if that is the .cre name it also has to be assigned as the DV, and either way if SK#ENF is running the script (it looks like he is) then there will be trouble.

ideas:
342 DisplayStringHeadDead(O:Object*,I:StrRef*)

318 ForceSpellRange(O:Target,I:Spell*Spell)
Untested, but I'm under the impression that this will force the specified spell if the target is within range of the spell.
Rabain
DisplayStringWait means the string displayed overhead does not display until other displaystrings have faded.

It's quite handy as I've found with displaystringhead you have to be right on with your Waits inbetween or you don't have enough time to read them and it can be time consuming trying to find the correct timing.

The only downside is that unless you have a decent amount of text to read it can seem a bit slow...especially in a cutscene!
Cuv
Hi again.... worked up a little script for you on how I would handle this.

I would run this as two cutscenes, two seperate blocks in the first. I have added comments as to why.

// SK#CUT1
CODE

IF
    True()
THEN
    RESPONSE #100
        CutSceneId("SK#ENF") // Death variable of creature running script
            SmallWait(4)  // small wait to get the player's attention
            ForceSpellPoint([608.304],CUTSCENE_METEOR_SWARM))
            Wait(14)  // This spell has long duration, might want to use another
        ForceSpell("SK#LICH",FLASHY_DEATH_3) // actually kills target chunks
        Wait(2)  // gives time for spell to finish
        DisplayStringWait(Myself,~No more time for regrets. It is done!~)
        Wait(2)  // added an extra line to give the second block time to run
        SetGlobal("SK#CUT1","AREA#",1)  // safety feature.
        StartCutScene("SK#CUT2") // Goes to cutscene to start dialog
END

IF
    True()
THEN
    RESPONSE #100
        CutSceneId("SK#LICH")
        DisplayStringHead(Myself,~I am sorry, my wife... for being unable to give you the child you wanted.~)
END


And the second...

// SK#CUT2
CODE


IF
    True()
THEN
    RESPONSE #100
        CutSceneId("SK#ENF")
        Wait(1)
        StartDialogueNoSet(Player1)
END




This 'should' work... but havent tested it myself. Hope it helps

Cuv
diana
Can also try doing this -

IF
True()
THEN
RESPONSE #100
CutSceneId("SK#ENF")
Wait(1)
ForceSpell("SK#LICH",CUTSCENE_METEOR_SWARM))
Wait(3)
ForceSpell("SK#LICH",FLASHY_DEATH_3))
Wait(3)
DisplayStringWait("SK#LICH",~I am sorry, my wife... for being unable to give you the child you wanted.~)
ActionOverride("SK#LICH",Kill(Myself))
Wait(2)
StartDialogueNoSet(Player1)
END

If the lich has been killed by the meteor swarm and flashy death, try this instead of DisplayStringWait and remove the line for him to kill himself.

342 DisplayStringHeadDead(O:Object*,I:StrRef*)
See DisplayStringHead(). This just targets a dead object.

Also, take a look at Actions in the IEDSP -- in the sample they show for cutscenes with both Anomen and Surley they took out the EndCutSceneMode() line before starting a dialog
cmorgan
QUOTE(Rabain @ May 14 2007, 02:20 PM) *

It's quite handy as I've found with displaystringhead you have to be right on with your Waits inbetween or you don't have enough time to read them and it can be time consuming trying to find the correct timing.
The only downside is that unless you have a decent amount of text to read it can seem a bit slow...especially in a cutscene!


I am definitely interested in this - I have been very conservative in applying the IESDP, but would love to see some examples, if it is ok, so i can play with the idea. Do you use this in something released, so I can stealborrow the idea and play with it a bit, please?
Amazor'dra
Thanks everyone for the help. I'll try out those methods as soon as I am able to--I can't right now, stuck in an art workshop and then have to go to a developer meeting.

Good stuff. smile.gif

QUOTE
ForceSpell("SK#LICH",FLASHY_DEATH_3) // actually kills target chunks


Hadn't been too sure if this just created the graphic of a character explosively dying, or also killed the character while playing the graphic, hence why I added the Kill() action to be safe.

DisplayStringWait is especially nifty if you want an NPC to draw the player's attention to something, that doesn't warrant an entire banter about it.
Vlad
Try to run the majority of cutscenes for Player1, i.e. CutSceneId(Player1), and ActionOverride all other creatures. This solves most of the problems with hanging cutscenes (if all other problems are solved smile.gif ).
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2024 Invision Power Services, Inc.