Scripts:Three-frame walking

From OHRRPGCE-Wiki

This script lets you use three-frame walkabout animations (actually consisting of a four-frame standing-leftstep-standing-rightstep animation cycle). By default it causes all NPCs and heroes to use 3 frame animations. If you don't want to draw these, then you can add an addition if statement to cause some to be skipped.

It can be combined with the walktall scripts.

An example tech demo is available at [1], which uses both threeframe.hss and walktall.hss.

This script won't work properly if you use four different frames instead of repeating the neutral/standing frame. However it could be adapted for more frames by an advanced user.

Heroes and NPCs will not automatically return to the neutral/standing frame when not moving. Unfortunately that is harder; here is a partial solution for that.

# threeframe.hss
# Three-frame walking animation script
#
# To use this script, draw your walkabout sprites
# to use two consecutive walkabout spritesets.
# In the first spriteset each direction should contain:
#   UP neutral frame, UP walking frame 1, RIGHT neutral frame, RIGHT walking frame 1, ...
# The second spriteset should be:
#   UP neutral frame, UP walking frame 2, RIGHT neutral frame, RIGHT walking frame 2, ...
# If some of your walkabouts have two frames and others have 3
# frames, then you can add an if condition to the "three frame walking update"
# script to skip over some graphics. See that script for an example.
#
# Next, import this script file into your game, and set
# "start three frame walking" as the newgame and loadgame special script
# triggers in the General Game Data menu.
#
# This script is fully compatible with the walktall scripts or most other scripts
# that modify either hero or npc walkabout set numbers, or hero or npc
# sprite slices directly. Just call "embiggen heroes" and "embiggen npcs" from the
# map autorun script as normal.


# ID of the timer to use
define constant(15, timer:three frame walking)
# Slice extradata slot to use for metadata
define constant(2, extradata:three frame walking)

# Set this script as the newgame and loadgame scripts, or call it from those scripts
plotscript, start three frame walking, begin
  three frame walking eachtick
end


script, three frame walking eachtick, begin
  # Update hero sprites
  variable (hero, slice)
  for (hero, 0, 3) do (
    # Check this caterpillar party slot isn't empty
    if (hero by rank(hero) < 0) then (continue)
    slice := lookup slice(sl:walkabout sprite component, get hero slice(hero))
    three frame walking update(slice)
  )

  # Update npc sprites
  variable (npcid, i, npcref)
  for (npcid, 0, 199) do (
    for (i, 0, npc copy count(npcid) -- 1) do (
      npcref := npc reference(npcid, i)
      slice := lookup slice(sl:walkabout sprite component, get npc slice(npcref))
      three frame walking update(slice)
    )
  )

  # This schedules the script to run again next tick, continuing forever
  set timer (timer:three frame walking, 0, 1, @three frame walking eachtick)
end

# Update a hero's or NPC's walkabout sprite slice 
script, three frame walking update, slice, begin
  variable (current spriteset)
  current spriteset := get spriteset number(slice)

  # If you want to exclude some walkabouts from three-frame animations, you can
  # add a check like the following here:
  #if (current spriteset < 10 || current spriteset > 18) then (exit script)

  variable (extradata, previous frame, current frame, previous spriteset, base spriteset)
  current frame := get sprite frame(slice), and, 1

  # Load metadata
  extradata := get slice extra(slice, extradata:three frame walking)
  previous frame := extradata, mod, 10
  previous spriteset := (extradata / 10), mod, 10 000
  base spriteset := (extradata / 100 000)

  if (previous spriteset <> current spriteset) then (
    # If the spriteset changes for some external reason, such as a change in party
    # order or a call to setheropicture, then we need to reset base spriteset
    base spriteset := current spriteset
  ) else (

    if (current frame <> previous frame) then (
      if (current frame == 0) then (
        # Change to the other spriteset.
        # (if you want more frames, change this part, and use N - 1 spritesets
        # for N frames)
        if (current spriteset == base spriteset) then (
          current spriteset := base spriteset + 1
        ) else (
          current spriteset := base spriteset
        )
        set spriteset number(slice, current spriteset)
      )
    )
  )
  # Store metadata
  extradata := current frame + current spriteset * 10 + base spriteset * 100 000
  set slice extra(slice, extradata:three frame walking, extradata)
end

See Also[edit]