
################################################################
# From http://rpg.hamsterrepublic.com/ohrrpgce/Scripts:Hero_will_move

# Returns the direction the hero will try to move, or else -1
script, want to move direction, begin
  return (-1)

  # If a textbox is up or player is suspended, the hero can't move
  if (current textbox > -1 || player is suspended) then (exit script)

  # Nor if a menu is up which suspends gameplay.
  # A more complicated menu check could be required if you are using fancy scripted menus that are always visible.
  if(top menu) then(exit script)

  variable(best dir, best time, time)
  best dir := -1
  best time := 999999

  subscript, check key, key, dir, begin
    time := keypress time(key)
    if (key is pressed(key) && time < best time) then (
      best dir := dir
      best time := time
    )
  end

  check key (right key, right)
  check key (left key, left)
  check key (down key, down)
  check key (up key, up)
  return (best dir)
end

# This will return true if hero 0 will start a new step
# this tick because of player input. There are no commands
# that can tell you that directly: you have to figure it out
# by checking keypresses and for obstructions.
# Note: this doesn't handle all edge cases, like multiple NPCs
# on one tile, NPCs over the edge of the map, or the hero already in motion.
script, hero will move, begin
  variable (dir, npc)

  # If a textbox is up or player is suspended, the hero can't move
  if (current textbox > -1 || player is suspended) then (exit returning (false))

  # Check for player input
  dir := want to move direction
  if (dir == -1) then (exit returning (false))

  # If there's a wall in the way, nothing will happen (unless walls are suspended...)
  if (check hero wall(0, dir)) then (exit returning (false))

  # Check for an NPC in the way which you can't step on
  # (this isn't correct either if obstruction is suspended, or other edge cases)
  npc := npc at spot (hero x(0) + dir x(dir), hero y(0) + dir y(dir))
  if (npc && readNPC(npc, NPCstat:activation) <> NPCactivation:stepon) then (exit returning (false))

  # OK, you will start walking in this direction
  return (true)
end


################################################################
# From http://rpg.hamsterrepublic.com/ohrrpgce/Scripts:Hero_will_move#next_leader_pixel_x.2Fy


# Guess the direction that the leader will move this tick, or -1 if they won't move.
script, next leader move direction, begin
  if (hero is walking(0)) then (
    return (hero direction(0))
  ) else if (hero will move) then (
    return (want to move direction)
  ) else (
    return (-1)
  )
end

# This only returns the position of the leader
script, next leader pixel x, begin
  variable(ret, dir)
  ret := hero pixel x
  dir := next leader move direction
  if (dir <> -1) then (
    ret += get hero speed(0) * dirX(dir)
  )
  return (ret)
end

# This only returns the position of the leader
script, next leader pixel y, begin
  variable(ret, dir)
  ret := hero pixel y
  dir := next leader move direction
  if (dir <> -1) then (
    ret += get hero speed(0) * dirY(dir)
  )
  return (ret)
end


################################################################
# From http://rpg.hamsterrepublic.com/ohrrpgce/Scripts:Hero_will_move#next_camera_pixel_x.2Fy


global variable(1, next camera pixel x)
global variable(2, next camera pixel y)

# Updates the values of the "next camera pixel x/y" global variables.
# Camera following NPCs or slices are not supported!
script, calculate next camera pixel xy, begin
  variable(destx, desty, diff, cam dir, cam speed)
  variable(mapw, maph, screenw, screenh)
  screenw := slice width(sprite layer)
  screenh := slice height(sprite layer)
  mapw := map width * 20
  maph := map height * 20

  next camera pixel x := camera pixel x
  next camera pixel y := camera pixel y
  # Check value of gen(genCameraMode)
  if (read general(45) == 0) then (   # herocam (camera following hero)
    # Offset from the top-left of the hero sprite to the topleft of the screen
    next camera pixel x := next leader pixel x -- (screenw -- 20) / 2
    next camera pixel y := next leader pixel y -- (screenh -- 20) / 2
  ) else if (read general(45) == 2) then (  #pancam
    cam dir := read general(46)
    cam speed := read general(48)
    next camera pixel x += dirX(cam dir) * cam speed
    next camera pixel y += dirY(cam dir) * cam speed
  ) else if (read general(45) == 3) then (  #focuscam
    destx := read general(46)
    desty := read general(47)
    cam speed := read general(48)
    diff := destx -- camera pixel x
    if (abs(diff) <= cam speed) then (
      next camera pixel x := dest x
    ) else (
      next camera pixel x += sign(diff) * cam speed
    )
    diff := desty -- camera pixel y
    if (abs(diff) <= cam speed) then (
      next camera pixel y := dest y
    ) else (
      next camera pixel y += sign(diff) * cam speed
    )
  )

  # Crop to map edge
  if (next camera pixel x < 0) then (next camera pixel x := 0)
  if (next camera pixel x > mapw -- screenw) then (next camera pixel x := mapw -- screenw)
  if (next camera pixel y < 0) then (next camera pixel y := 0)
  if (next camera pixel y > maph -- screenh) then (next camera pixel y := maph -- screenh)
end


################################################################
# From http://rpg.hamsterrepublic.com/ohrrpgce/Scripts:Fake_Parallax


define constant(4, troll mountain parallax timer)

plotscript, troll mountain autorun, begin
  update troll mountain parallax
end

script, update troll mountain parallax, begin
  variable(sl, mapw, maph, screenw, screenh, layerw, layerh)
  if(current map <> map:troll mountain) then(
    stop timer(troll mountain parallax timer)
    #(The following is only needed if 'recreate map slices when leaving map' is off)
    sl := lookup slice(sl:map layer 0)
    set slice x(sl, 0)
    set slice y(sl, 0)
    exit script
  )
  mapw := map width * 20
  maph := map height * 20
  screenw := slice width(sprite layer)
  screenh := slice height(sprite layer)
  layerw := 50 * 20
  layerh := 20 * 20
  sl := lookup slice(sl:map layer 0)
  calculate next camera pixel xy
  set slice x(sl, (next camera pixel x * (mapw -- layerw) / (mapw -- screenw)))
  set slice y(sl, (next camera pixel y * (maph -- layerh) / (maph -- screenh)))
  # Set the script to run again next tick
  set timer(troll mountain parallax timer, 0, 1, @update troll mountain parallax)


################################################################
# Specific to this test

  if (not(cam slice)) then (cam slice := create rect(20,20))
  putslice(cam slice, nextcamerapixelx, nextcamerapixely)
  set parent(cam slice, lookupslice(sl:maplayer2))
end

# This slice indicate the expected position of the camera (top left corner of screen)
global variable(3, cam slice)

global variable(4, npc control)

define constant(1, npc cursor)

plotscript, on keypress, begin
  if (key is pressed(key:r)) then (pan camera(right, 10, 5), update troll mountain parallax)
  if (key is pressed(key:f)) then (focus camera(80, 20, 6), update troll mountain parallax)
  if (key is pressed(key:h)) then (camera follows hero, update troll mountain parallax)
  if (key is pressed(key:p)) then (put camera(70 * 20, 20 * 20), update troll mountain parallax)

  if (key is pressed(key:n)) then (npc control := true, camera follows npc(npc cursor))

  if (npc control) then (
    if (npc is walking (npc cursor) == false) then (
      # Only move the NPC after they've finished the previous movement,
      # also use elseif to prevent moving in two directions at once.
      if      (key is pressed (key:Left))  then (walk npc (npc cursor, left, 1))
      else if (key is pressed (key:Right)) then (walk npc (npc cursor, right, 1))
      else if (key is pressed (key:Up))    then (walk npc (npc cursor, up, 1))
      else if (key is pressed (key:Down))  then (walk npc (npc cursor, down, 1))
    )
  )
end
