Cutscenes module

Module for TR4's in-game cutscenes, the animated scenes stored in cutseq.pak and started by a cutscene trigger. A cutscene plays once: the engine remembers which ones have run, and a script may consult or rewrite that memory. The cutscene levels of TR1-TR3, which the game flow lists and /cut plays, are a different thing: see trx.game.cutscenes.

Indexing

Indexing the module reaches a cutscene by the number a trigger names it with. #trx.cutscenes is how many the game can play, and pairs() walks those in order; the numbers past them are reachable as well, because the engine remembers any of them as played.

Example:

trx.cutscenes[30]:on_frame(function(cutscene, frame_num)
  trx.log.info("frame " .. frame_num .. " of " .. cutscene.num)
end)

Properties

  • trx.cutscenes.current (trx.cutscenes.Cutscene). The cutscene playing, or nil if none is. (read-only)
  • trx.cutscenes.frame_num (trx.cutscenes.FrameNum). Which frame of the running cutscene is on screen, or nil if none is running. A cutscene's actors are animation tracks rather than items, so nothing in it can be triggered or listened to; naming a frame is how a script acts part-way through one, as the original game does. (read-only)
  • trx.cutscenes.signals.is_playing (trx.signal.Signal). Says when a cutscene takes the screen, and when it gives it back. (read-only)
  • trx.cutscenes.signals.is_active (trx.signal.Signal). Signals when a cutscene has the screen, including during its fades. (read-only)
  • trx.cutscenes.is_playing (boolean). Whether a cutscene is on screen. (read-only)
  • trx.cutscenes.is_active (boolean). Whether a cutscene has the screen, including during its fades. Use this to keep an interface off while the cutscene is active. (read-only)
  • trx.cutscenes.count (integer). How many cutscenes this game can play. 0 where it has none, which is every game but TR4 and a TR4 install with no cutseq.pak beside its levels. (read-only)
  • trx.cutscenes.actor_count (integer). How many actors the running cutscene has, or 0 if none is running. (read-only)
  • trx.cutscenes.fov (trx.math.Angle). Field of view a cutscene plays at. TR4 uses 11488, against 14560 for ordinary play.
  • trx.cutscenes.letterbox (number). Depth of each cinematic bar, as a fraction of the screen height. 0 removes them. A change made while a cutscene plays moves the bars to the new depth.

Structures

  • trx.cutscenes.Num

    Cutscene number, as a cutscene trigger names it. Counted from 0.

  • trx.cutscenes.FrameNum

    A frame's number within the cutscene it belongs to. Counted from 0.

  • trx.cutscenes.ActorNum

    Which of a cutscene's actors. Actor 0 is Lara, who is posed rather than drawn as an actor; the cast a scene brings with it starts at 1. Counted from 0.

  • trx.cutscenes.NodeNum

    Which of an actor's meshes, the root being the first. Counted from 0.

  • trx.cutscenes.Cutscene

    One of the scenes a cutscene trigger can name. A number the pak holds no scene for is still one of these, because the engine remembers it as played the same way; play is what such a number has nothing to do.

    Properties:

    • frame_num: trx.cutscenes.FrameNum. Which frame of this scene is on screen, or nil unless it is the one playing. (read-only)
    • is_played: boolean. Whether a trigger naming this number has already been answered. True keeps its trigger from firing; writing false lets it run again.
    • is_playing: boolean. Whether this scene is the one on screen. (read-only)
    • num: trx.cutscenes.Num. Which scene this is. (read-only)

    Methods:

    • cutscene:on_end(callback)
      Happens once this scene has finished and what it interrupted is back. trx.events.on_cutscene_end, narrowed to this cutscene.

      Parameters:

      • callback (function). What to run when it happens. Called with:

      Returns: trx.events.Listener. The attached handler.

    • cutscene:on_frame(callback)
      Happens on every frame of this scene, before the frame is posed.

      A cutscene has no items to listen to. Its actors are animation tracks, so the frame number is the only thing a script can act on.

      trx.events.on_cutscene_frame, narrowed to this cutscene.

      Parameters:

      Returns: trx.events.Listener. The attached handler.

      Example:

      trx.cutscenes[5]:on_frame(function(cutscene, frame_num)
        if frame_num == 1350 then
          -- something happens here
        end
      end)
      
    • cutscene:on_start(callback)
      Happens when this scene's first frame is about to show. trx.events.on_cutscene_start, narrowed to this cutscene.

      Parameters:

      • callback (function). What to run when it happens. Called with:

      Returns: trx.events.Listener. The attached handler.

    • cutscene:play([opts])
      Plays this scene. Does nothing if one is already playing or the game holds no scene for this number.

      Parameters:

      • opts (table, optional). How to play it.

        Keys:

        • fade (boolean, optional, default true). Whether to fade the scene out before the first frame. A cutscene that opens a level passes false: the original game holds the screen black rather than showing the level for a moment first, and the scene's own fade in follows either way.

      Example:

      trx.cutscenes[28]:play()
      

Functions

  • trx.cutscenes.signals
    The signals a cutscene speaks through, for a script that would rather hear about a change than ask after one.

  • trx.cutscenes.play(num, [fade])
    Deprecated. Call trx.cutscenes.Cutscene:play instead.

    Plays a cutscene, fading the scene out first. Does nothing if one is already playing or the game has no cutscene data.

    Parameters:

    • num (trx.cutscenes.Num).
    • fade (boolean, optional). Whether to fade the scene out before the first frame. Defaults to true. A cutscene that opens a level passes false: the original game holds the screen black rather than showing the level for a moment first, and the scene's own fade in follows either way.
  • trx.cutscenes.set_actor_visible(actor, visible)
    Whether an actor is drawn. A scene brings its whole cast on from its first frame, so an actor who is only due later is hidden until then, as the original game hides one.

    It lasts as long as the cutscene, and every actor starts out visible.

    Parameters:

    Example:

    trx.events.on_cutscene_start(function(num)
      if num == 9 then
        trx.cutscenes.set_actor_visible(3, false)
      end
    end)
    
  • trx.cutscenes.set_node_mesh(actor, node, object, [mesh_num])
    Draws another object's mesh in place of the one an actor's node carries. This is how a talking head goes on a body: the speech-head objects hold a mouth in each shape, and swapping between them while a line plays is what the original game animates speech with.

    Raises if this level does not carry the object.

    Parameters:

    Example:

    trx.cutscenes.set_node_mesh(1, 21, trx.catalog.objects.actor_1_speech_head_1)
    
  • trx.cutscenes.clear_node_mesh(actor, node)
    Takes the override back off, leaving the mesh the actor's own object gives that node.

    Parameters:

  • trx.cutscenes.is_played(num)
    Deprecated. Read trx.cutscenes.Cutscene.is_played instead.

    Whether a cutscene trigger naming this number has already been answered.

    Parameters:

    Returns: boolean. True once it has run, which is what keeps its trigger from firing again.

  • trx.cutscenes.set_played(num, played)
    Deprecated. Write trx.cutscenes.Cutscene.is_played instead.

    Marks a cutscene as played or unplayed. Marking one as played keeps its trigger from firing; unmarking one lets it run again.

    A trigger may name a number the game has no cutscene for - TR4 uses 32 to ask for a full-motion video - and the engine remembers those the same way, so trx.events.on_cutscene_trigger hears about each of them once. This is what clears that memory, and it takes any number a trigger may carry, not only the ones trx.cutscenes.play accepts.

    Parameters:

  • trx.cutscenes.forget_played()
    Forgets every cutscene, so all of them may run again.

  • trx.cutscenes.set_lara_return(pos, [rot])
    Places Lara where the next cutscene to end leaves her. A cutscene stands her at its own origin while it plays and puts her back where it found her afterwards; this says to put her somewhere else instead, as the original game does for the scenes that carry her along.

    It holds for one cutscene, whether named before trx.cutscenes.play or while the scene runs, and is forgotten once she has been placed.

    Parameters:

    Example:

    trx.events.on_cutscene_start(function(num)
      if num == 12 then
        trx.cutscenes.set_lara_return({ x = 38912, y = 2048, z = 51200 })
      end
    end)
    
  • trx.cutscenes.set_lara_shadow_bounds(bounds)
    Gives Lara's shadow another box for the running cutscene. A scene holds one box for the whole of it, rather than the box her pose would make, so that her shadow keeps a steady size while the scene moves her; this names a different one. A wide box is how the original game makes her shadow read as the jeep's when she arrives at Karnak.

    It holds for one cutscene, whether named before trx.cutscenes.play or while the scene runs, and the next scene starts from the ordinary box again.

    Parameters:

    Example:

    trx.events.on_cutscene_start(function(num)
      if num == 12 then
        trx.cutscenes.set_lara_shadow_bounds({
          min_x = -600, min_y = -777, min_z = -600,
          max_x = 600, max_y = 1, max_z = 600,
        })
      end
    end)