------------------------------------------------------------------------
-- Copyright (C) 2002 Daniel Heck
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; either version 2
-- of the License, or (at your option) any later version.
--  
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--  
-- You should have received a copy of the GNU General Public License along
-- with this program; if not, write to the Free Software Foundation, Inc.,
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
------------------------------------------------------------------------


------------------------------------------------------------------------
-- FUNCTIONS
------------------------------------------------------------------------
function Rect(xx,yy,ww,hh)
    return {x=xx, y=yy, w=ww, h=hh}
end

function progress(percent)
    enigma.DisplayTextCentered("menufont", 
                               "Loading game data..."..percent.."%")
end


modeltag = 0
function unique_modelname()
    modeltag = modeltag + 1
    return "xmodel" .. modeltag
end

-- Define a new image model.  'name' is the name of the model being created
-- and 'opt' contains optional information about the image file.  The following
-- fields can be set in 'opt':
--
--     * filename
--     * xoff,yoff (hotspot coordinates inside the image)
--
-- Suitable default values are used for all options
function def_image(name, opt)
    opt = opt or {}
    name = name or unique_modelname()
    fname = (opt.filename or name)
    opt = opt or {}
    enigma.DefineImage(name, fname, opt.xoff or 0, opt.yoff or 0)
    return name
end

-- Define multiple image models at once.  Use the same options for all
-- of them.
function def_images(names, opt)
    opt = opt or {}
    for i,name in names do
	def_image(name,opt)
    end
end

function def_subimages(name, options)
    local opts = options or { }
    local w = opts.w or 1
    local h = opts.h or 1
    local imgw = opts.imgw or 32
    local imgh = opts.imgh or 32
    local xoff = opts.xoff or 0
    local yoff = opts.yoff or 0
    local modelname = opts.modelname or name

    local imagelist={}
    local cnt = 1
    for x=1,w do
        for y=1,h do
            local r=Rect(imgw*(x-1),imgh*(y-1),imgw,imgh)
            tinsert(imagelist, name..cnt)
            enigma.DefineSubImage(modelname..cnt, name, xoff,yoff, r)
            cnt = cnt+1
        end
    end
    return imagelist
end

function def_stone(name, shmodel, opt)
    opt = opt or {}
    shmodel = shmodel or "sh-solid"
    opt.filename = opt.filename or name
    enigma.DefineShmodel(name, def_image(nil, opt), shmodel)
end

function def_stones(names)
    for i,name in names do def_stone(name) end
end

-- Define a shaded model named `name' with texture model `fg' and
-- shadow model `bg'.  Both are real models (not names of image files), so 
-- you can combine animated images with shadows etc.
function def_shmodel(name, fg, bg)
    enigma.DefineShmodel(name, fg, bg)
end

function def_overlay(name, imglist)
    enigma.DefineOverlayImage(name, imglist)
end

function def_solidstone(name, front)
    enigma.DefineShmodel(name, front, "sh-solid")
end

----------------
-- ANIMATIONS --
----------------

-- Generate a list of frame names by appending increasing numerical
-- prefixes to a base name.  For example, 'framenames("hello", 1,2)'
-- yields {"hello_0001", "hello_0002"}.
-- [Filenames like this are created by Gimp's "Video/Split Image.."
-- tool.]

function framenames(prefix, first, last)
    local fn = {}
    for i=first,last do
	tinsert(fn, prefix .. format("_%04d", i))
    end
    return fn
end

-- Build a list of frames from a list of model names and a constant
-- duration.
function buildframes(names, msec)
    local a={}
    for i,n in names do a[i] = {n, msec} end
    return a
end

-- Build a list of frames from (1) a list of names and (2) a list of
-- frame durations.  These two list are assumed to have the same
-- number of entries, or, more generally, to have the same index set.
function composeframes(namelist, mseclist)
    local a={}
    for i,n in namelist do a[i] = {n, mseclist[i]} end
    return a
end


-- Given a list of frames, this function generates a new framelist
-- with for a ping-pong style animation.  (For example, an "abcd"
-- style animation would result in an "abcddcba"-style one.)

function pingpong(framelist)
    local a=framelist
    local n=getn(framelist)
    for i = 0,n-1 do
	a[n+i+1] = framelist[n-i]
    end
    return a
end

function repeat_frames(framelist, blocksize, cnt)
    local a={}
    for i=1,getn(framelist),blocksize do
	for j=1,cnt do
	    for k=i,i+blocksize-1 do
		tinsert(a,framelist[k])
	    end
	end
    end
    return a
end

function repeatanim(framelist)
    return repeat_frames(framelist, getn(framelist), 2)
end

function reverseframes(framelist)
    local a={}
    for i=getn(framelist),1,-1 do
	tinsert(a, framelist[i])
    end
    return a
end

-- Define an animation from a list of images.  `frames' is a
-- framelist, as built with `framenames()', but the model names in
-- this list are interpreted as image filenames.

function def_anim_images(name, frames, opt)
    opt = opt or {}
    enigma.DefineAnim(name, opt.loop)
    for i=1,getn(frames) do
	local frame=frames[i]
	opt.filename = frame[1]
	local immodel = def_image(nil, opt)
	enigma.AddFrame(name, immodel, frame[2])
    end
end

function def_anim(name, frames, loop)
    enigma.DefineAnim(name, loop)
    for i=1,getn(frames) do
	local frame = frames[i]
	enigma.AddFrame(name, frame[1], frame[2])
    end
end
    
------------------------------------------------------------------------
-- MODELS
------------------------------------------------------------------------

----------------------
-- General settings --
----------------------
enigma.SetTileSize(32, 32)

def_image("invisible")

------------------
-- Actor models --
------------------
progress(0)

def_image("sh-whiteball-small", {xoff=-3, yoff=-3})
def_shmodel("ac-whiteball-small", 
            def_image(nil, {filename="ac-whiteball-small", xoff=-6, yoff=-6}),
            "sh-whiteball-small"
        )
namelist=def_subimages("ac-whiteball-small-fall",
                       {h=5, imgw=12, imgh=12, xoff=-6, yoff=-6})
def_anim("ac-whiteball-small-fall",
         composeframes(namelist,{70,65,60,55,50,50}))
def_image("ac-whiteball-small-fallen",
          {filename="invisible", xoff=-4, yoff=-4})

namelist=def_subimages("ac-whiteball-small-shatter",
                       {h=5, imgw=20, imgh=20, xoff=-10, yoff=-10})
def_anim("ac-whiteball-small-shatter", buildframes(namelist, 60))
def_image("ac-whiteball-small-shattered", {xoff=-8, yoff=-9})


def_image("sh-blackball", {xoff=-6, yoff=-6})

enigma.DefineShmodel("ac-blackball",
    def_image(nil, {filename="ac-blackball",xoff=-12,yoff=-12}),
    "sh-blackball"
)
enigma.DefineShmodel("ac-whiteball",
    def_image(nil, {filename="ac-whiteball",xoff=-12,yoff=-12}),
    "sh-blackball"
)

-- Shattering black ball --
namelist=def_subimages("ac-blackball-shatter",
                       {h=5, imgw=40, imgh=40, xoff=-20, yoff=-20})
def_anim("ac-blackball-shatter", buildframes(namelist, 60))
def_image("ac-blackball-shattered", {xoff=-20, yoff=-20})

-- Falling black ball --
namelist=def_subimages("ac-blackball-fall",
                       {h=10, imgw=24, imgh=24, xoff=-12, yoff=-12})
def_anim("ac-blackball-fall", 
         composeframes(namelist,{70,65,60,55,50,50,50,50,50,50,50}))

def_image("ac-blackball-fallen", 
          {filename="invisible", xoff=-4, yoff=-4})

-- Jumping black ball --
namelist=def_subimages("ac-blackball-jump", {h=4, imgw=32, imgh=32, xoff=-16, yoff=-16})
def_anim("ac-blackball-jump",
         pingpong(buildframes(namelist, 70)))
-- XXX add shadows


-- Black marble in inventory  --
def_image("inv-blackball")


------------------
-- Floor models --
------------------
progress(10)

function def_floors(floorlist)
    for i,name in floorlist do
	def_image(name)
    end
end

function def_randfloor(name, imagelist)
    def_floors(imagelist)
    enigma.DefineRandmodel(name, imagelist)
end

-- _si for _subimage
function def_randfloor_si(name, height)
    imagelist=def_subimages(name, {h=height})
    enigma.DefineRandmodel(name, imagelist)
end

if enigma.WizardMode > 0.0 then
    def_subimages("fl-gradient-wiz", {modelname="fl-gradient",w=6, h=4})
else
    def_subimages("fl-gradient", {w=6, h=4})
end

def_image("fl-rock", {filename="fl-rock1"})
def_floors{"fl-abyss"}
def_floors{"fl-dunes", "fl-sand", "fl-wood", "fl-bluegreen", "fl-bluegreenx"}
def_floors{"fl-inverse"}
def_image("fl-normal")
def_randfloor("fl-hay",{"fl-hay1", "fl-hay2"})
def_randfloor("fl-space", {"fl-space1", "fl-space2", "fl-space3"})
def_randfloor("fl-rough", {"fl-rough1", "fl-rough2", "fl-rough3","fl-rough4","fl-rough5"})
def_randfloor("fl-brick", {"fl-brick1", "fl-brick2", "fl-brick3"})

def_randfloor_si("fl-gray", 5)
def_randfloor_si("fl-leaves", 3)
def_randfloor_si("fl-metal", 5)
def_randfloor_si("fl-plank", 4)
def_randfloor_si("fl-water", 4)
def_randfloor_si("fl-woven", 5)
def_randfloor_si("fl-marble", 4)
--
-- Bridges
--
def_image("fl-bridgea-open")
def_image("fl-bridgea-closed")
namelist=def_subimages("fl-bridgea", {h=10})
frames = buildframes(namelist,70)
def_anim("fl-bridgea-opening", reverseframes(frames))
def_anim("fl-bridgea-closing", frames)


def_image("fl-bridgex-open")
def_image("fl-bridgex-closed")
namelist=def_subimages("fl-bridgex", {h=9})
frames = buildframes(namelist,70)
def_anim("fl-bridgex-opening", frames)
def_anim("fl-bridgex-closing", reverseframes(frames))


def_image("fl-bridgey-open")
def_image("fl-bridgey-closed")
namelist=def_subimages("fl-bridgey", {h=9})
frames = buildframes(namelist,70)
def_anim("fl-bridgey-opening", frames)
def_anim("fl-bridgey-closing", reverseframes(frames))

-----------------
-- Item models --
-----------------
progress(20)

def_images{"it-document", "it-hill", "it-tinyhill", 
    "it-hollow", "it-tinyhollow"}

def_images{"it-blackbomb","it-dynamite", "it-extralife",
    "it-magicwand", "it-laserh", "it-laserv", "it-laserhv",
    "it-hammer",
    "it-umbrella",
    "it-floppy",
    "it-key",
    "it-key_a",
    "it-key_b",
    "it-key_c",
    "it-trigger", "it-trigger1",
    "it-spring1"
}

-- Coins --
def_images{"it-coin", "it-coin1", "it-coin2", "it-coin4"}

-- Burning dynamite --
dyn_frames=buildframes(framenames("it-dynamite-burning", 1,15), 100)
def_anim_images("it-dynamite-burning", repeat_frames(dyn_frames,3,2))

-- Burning bomb --
dyn_frames=buildframes(framenames("it-blackbomb-burning", 1,9), 100)
def_anim_images("it-blackbomb-burning", repeat_frames(dyn_frames,3,2))

-- Explosion --
def_anim_images("expl", {{"expl", 1000}})

-- Shogun dots --
def_anim("it-shogun1", pingpong(buildframes(def_subimages("it-shogun-small", {h=3}), 160)), 1)
def_anim("it-shogun2", pingpong(buildframes(def_subimages("it-shogun-med", {h=3}), 160)), 1)
def_anim("it-shogun3", pingpong(buildframes(def_subimages("it-shogun-big", {h=3}), 160)), 1)

------------------
-- STONE MODELS --
------------------
progress(30)

-- stone shades
def_image("sh-solid")
def_image("sh-grate1")
def_images{"sh-grate2"}
def_image("sh-glass")

-- stone models
def_stone("st-glass", "sh-glass")
def_stone("st-rock1")
def_stone("st-rock2")
def_stone("st-rock3")
def_stone("st-brownie")
def_stone("st-marble")
def_stone("st-wood")
def_stone("st-grate1", "sh-grate1")
def_stone("st-grate2", "sh-grate2")
def_stone("st-swap")
def_stone("st-bombs", nil, {filename="st-bombs2"})
def_stone("st-greenbrown")
def_stone("st-stone_break", nil, {filename="st-stone_break"})
def_stone("st-brick")
def_stone("st-woven")
def_stone("st-brick_magic", nil, {filename="st-brick"})
def_stone("st-switch0", nil, {filename="st-switch2"})
def_stone("st-switch1", nil, {filename="st-switch1"})
def_stone("st-floppy0", nil, {filename="st-floppy1"})
def_stone("st-floppy1", nil, {filename="st-floppy2"})

def_stone("st-marble_hole")
def_stone("st-greenbrown_hole")
def_stone("st-rock3_hole")
def_stone("st-marble_move")
def_stone("st-greenbrown_move")
def_stone("st-rock3_move")
def_stone("st-key0", nil, {filename="st-key1"})
def_stone("st-key1", nil, {filename="st-key2"})

def_stone("st-death")
framelist=def_subimages("st-death-munch", {h=3})
def_anim("st-death-munch-anim", buildframes(framelist, 140))
def_solidstone("st-death-munch", "st-death-munch-anim")


-----------------
-- Oxyd Stones --
-----------------

-- Oxyd stones occur in different colors and different flavors and
-- for each combination of these two attributes we need animations
-- for the following internal states or state transitions:
--
--   (a) opening and closing
--   (b) blinking
--   (c) opened
--
-- Creating the required image files by hand would be tedious, so
-- we use a couple of specialized functions and overlays to create 
-- them automatically.

oxcolorspots = framenames("st-oxydbtempl", 2,9)
oxbulges = framenames("st-oxydbtempl", 10,14)

-- Define "fading in" and "fading out" animations for oxyd stones.
-- These two animations are combined with the stone images to 
-- produce the opening and closing animations for oxyd stones.

oxbaseimg = {
    a="st-oxyda-open_0001", 
    b="st-oxydbtempl_0001",
    c="st-oxydctempl_0001",
    d="st-oxyddtempl_0001"
}
oxopening_fms = {
    a = buildframes(framenames("st-oxyda-open", 2,10), 60),
    b = buildframes(framenames("oxydb-fadein", 1,14), 40),
    c = buildframes(framenames("oxydc-fadein", 1,5), 70),
    d = buildframes(framenames("oxydd-fadein", 1,5), 70),
}
oxclosing_fms = {
    a = reverseframes(oxopening_fms["a"]),
    b = reverseframes(oxopening_fms["b"]),
    c = reverseframes(oxopening_fms["c"]),
    d = reverseframes(oxopening_fms["d"]),
}

function make_oxydopenclose(flavor, color)
    local basename = "st-oxyd" .. flavor .. color
    local fadein = "oxyd"..flavor.."-fadein"
    local fadeout= "oxyd"..flavor.."-fadeout"

    def_overlay(basename.."-base", {oxbaseimg[flavor], oxcolorspots[color+1]})
    def_solidstone(basename, basename.."-base")
    enigma.DefineComposite(basename .. "-opening", basename, fadein)
    enigma.DefineComposite(basename .. "-closing", basename, fadeout) 
end


function make_oxydblink(flavor, color)
    local basename = "st-oxyd" .. flavor .. color .. "-blink"

    local images={oxbaseimg[flavor], oxcolorspots[color+1], "st-oxyd-questmark"}
    def_overlay(basename .. 1, images)
    def_overlay(basename .. 2, {oxbaseimg[flavor], oxcolorspots[color+1]})
    def_anim(basename.."-anim", 
             buildframes({basename .. 1,basename .. 2}, 500), 1)
    enigma.DefineShmodel(basename, basename .. "-anim", "sh-solid")
end

function make_oxydopened(flavor, color)
    local basename = "st-oxyd" .. flavor .. color .. "-open"
    local names = {}

    for i=1,getn(oxbulges) do
        local images={oxbaseimg[flavor],oxcolorspots[color+1],oxbulges[i]}
	names[i] = basename .. format("_%04d", i)
	def_overlay(names[i], images)
    end
    
    -- compose these images into an animation
    frames = pingpong(buildframes(names, 100))
    def_anim(basename .. "-anim", frames, 1)

    -- and finally add a shadow to make the model complete
    def_solidstone(basename, basename.."-anim")
end

function make_oxydmodel(flavor)
--    print ("making oxyd model for "..flavor)
    def_stone("st-oxyd"..flavor)

    local fadein = "oxyd"..flavor.."-fadein"
    local fadeout= "oxyd"..flavor.."-fadeout"
    def_anim_images(fadein, oxopening_fms[flavor])
    def_anim_images(fadeout, oxclosing_fms[flavor])

    for color=0,7 do
        make_oxydopenclose(flavor, color)
        make_oxydblink(flavor, color)
        make_oxydopened(flavor, color)
    end
end
make_oxydmodel("a")
make_oxydmodel("b")
progress(40)
make_oxydmodel("d")
make_oxydmodel("c")

progress(50)

-----------------
-- Laser stone --
-----------------
function make_laser(dir)
    laseron=framenames("st-laser"..dir, 1, 9)

    -- deactivated laser
    enigma.DefineOverlayImage("laser"..dir, {"st-laser-base", laseron[1]})
    def_solidstone("st-laser"..dir, "laser"..dir)

    -- activated laser
    names = {}
    for i=1,getn(laseron) do
	names[i] = "st-laseron"..dir .. format("_%04d", i)
	enigma.DefineOverlayImage(names[i], {"st-laser-base", laseron[i]})
    end
    frames = buildframes(names, 100)
    def_anim("st-laseron-anim"..dir, frames, 1)
    def_solidstone("st-laseron"..dir, "st-laseron-anim"..dir)
end

make_laser("-e")
make_laser("-s")
make_laser("-w")
make_laser("-n")

---------------------
-- Fake oxyd stone --
---------------------
def_stone("st-fakeoxyd", nil, {filename="st-oxydb"})
def_anim_images("fakeoxyd-blink",
                repeatanim(pingpong
                           (buildframes(framenames("st-fakeoxyd-blink", 1,4), 
                                        50))))
def_solidstone("st-fakeoxyd-blink", "fakeoxyd-blink")

-- Fart stone
def_stone("st-fart", nil, {filename="st-oxydb"})
def_anim_images("farting",
                repeatanim(pingpong
                           (buildframes(framenames("st-fakeoxyd-blink", 1,4), 
                                        50))))
def_solidstone("st-farting", "farting")

-- Actor impulse stone
namelist = def_subimages("st-stoneimpulse", {h=5})
def_solidstone("st-actorimpulse", "st-stoneimpulse2")
def_anim("actorimpulse-anim",
         pingpong(buildframes({namelist[4], namelist[5]}, 50)))
def_solidstone("st-actorimpulse-anim", "actorimpulse-anim")

-- Stone impulse stone
def_solidstone("st-stoneimpulse", namelist[1])
def_anim("stoneimpulse-anim", pingpong(buildframes(namelist, 50)))
def_solidstone("st-stoneimpulse-anim", "stoneimpulse-anim")

-- Thief stone
namelist = def_subimages("st-thief", {h=7})
def_anim("thief-anim", pingpong(buildframes(namelist, 80)))
def_solidstone("st-thief", namelist[1])
def_solidstone("st-thief-anim", "thief-anim")

-- Timer stone
def_anim_images("timer-anim",
                buildframes(framenames("st-timer", 1, 6),
                            80), {loop=1})
def_solidstone("st-timer", "timer-anim")
def_stone("st-timeroff", nil, {filename="st-timer_0001"})

progress(60)

-------------
-- Mirrors -- 
-------------

-- naming scheme for mirror models: 
--
--	st-{3mirror,pmirror}-{m,s}{o,t}[1234]
--
-- {m,s} -> movable or static
-- {o,t} -> opaque or transparent
-- 
-- The numbers map to actual orientations as follows:
--
--   NUMBER    TRIANG.M.   PLANE M.
--	1	south	    "-"
--	2	west	    "\"
--	3	north	    "|"
--	4	east	    "/"

function make_mirror(basename, baseimg, overlays)
    for i=1,4 do
	mname = basename .. i
	enigma.DefineOverlayImage(mname .. "-ovl", {baseimg, overlays[i]})
	enigma.DefineShmodel(mname, mname .. "-ovl", "sh-solid")
    end
end

mirror3_opaque = framenames("st-mirrortempl", 1, 4)
mirror3_transp = framenames("st-mirrortempl", 5, 8)
mirrorp_opaque = framenames("st-mirrortempl", 9, 12)
mirrorp_transp = framenames("st-mirrortempl", 13, 16)

make_mirror("st-3mirror-mo", "st-mirror-movable", mirror3_opaque)
make_mirror("st-3mirror-so", "st-mirror-static",  mirror3_opaque)
make_mirror("st-3mirror-mt", "st-mirror-movable", mirror3_transp)
make_mirror("st-3mirror-st", "st-mirror-static",  mirror3_transp)

make_mirror("st-pmirror-mo", "st-mirror-movable", mirrorp_opaque)
make_mirror("st-pmirror-so", "st-mirror-static",  mirrorp_opaque)
make_mirror("st-pmirror-mt", "st-mirror-movable", mirrorp_transp)
make_mirror("st-pmirror-st", "st-mirror-static",  mirrorp_transp)

-- OneWay --
def_stones{"st-oneway-n", "st-oneway-e", "st-oneway-w", "st-oneway-s"}


-- Coin dropping into slot --
namelist=def_subimages("st-coin2slot", {h=20})
def_anim("st-coin2slot-anim", buildframes(namelist, 20))
def_solidstone("st-coin2slot", "st-coin2slot-anim")

def_stone("st-coinslot")
def_stone("st-yellow")


progress(70)

-- Puzzle stones --
function make_puzzle(no)
    def_stone("st-puzzle"..no, nil, 
              {filename="st-puzzletempl_"..format("%04d", no)})
end
for i=1,16 do make_puzzle(i) end

-- Door --
def_image("st-doorh-open", {filename="st-doorh_0007"})
def_image("st-doorh-closed", {filename="st-doorh_0001"})
doorhframes = buildframes(framenames("st-doorh",1,7),60)
def_anim_images("st-doorh-opening", doorhframes)
def_anim_images("st-doorh-closing", reverseframes(doorhframes))

def_image("st-doorv-open", {filename="st-doorv_0007"})
def_image("st-doorv-closed", {filename="st-doorv_0001"})
doorvframes = buildframes(framenames("st-doorv",1,7),60)
def_anim_images("st-doorv-opening", doorvframes)
def_anim_images("st-doorv-closing", reverseframes(doorvframes))



-- Door_a --
def_image("st-doora-open", {filename="st-doora_0002"})
def_image("st-doora-closed", {filename="st-doora_0001"})
door_ahframes = buildframes(framenames("st-doora",1,2),60)
def_anim_images("st-doora-opening", door_ahframes)
def_anim_images("st-doora-closing", reverseframes(door_ahframes))

-- Door_b --
def_image("st-doorb-open", {filename="st-doorb_0008"})
def_image("st-doorb-closed", {filename="st-doorb_0001"})
door_bhframes = buildframes(framenames("st-doorb",1,8),60)
def_anim_images("st-doorb-opening", door_bhframes)
def_anim_images("st-doorb-closing", reverseframes(door_bhframes))

-- Door_c --
def_image("st-doorc-open", {filename="st-doorc_0002"})
def_image("st-doorc-closed", {filename="st-doorc_0001"})
door_chframes = buildframes(framenames("st-doorc",1,2),60)
def_anim_images("st-doorc-opening", door_chframes)
def_anim_images("st-doorc-closing", reverseframes(door_chframes))

-- Shogun stones --
def_images{"sh-shogun1","sh-shogun2", "sh-shogun4"}

def_stone("st-shogun1", "sh-shogun1")
def_stone("st-shogun2", "sh-shogun2")
def_stone("st-shogun4", "sh-shogun4")

def_overlay("st-shogun3o", {"st-shogun1", "st-shogun2"})
def_shmodel("st-shogun3", "st-shogun3o", "sh-shogun1")

def_overlay("st-shogun5o", {"st-shogun1", "st-shogun4"})
def_shmodel("st-shogun5", "st-shogun5o", "sh-shogun1")

def_overlay("st-shogun6o", {"st-shogun2", "st-shogun4"})
def_shmodel("st-shogun6", "st-shogun6o", "sh-shogun2")

def_overlay("st-shogun7o", {"st-shogun1", "st-shogun2", "st-shogun4"})
def_shmodel("st-shogun7", "st-shogun7o", "sh-shogun1")

progress(80)

-------------------
-- Bolder stones --
-------------------
bolder_base="st-bolder_0001"
bolder_arrows={
    n=framenames("st-bolder", 2,4),
    e=framenames("st-bolder", 5,7),
    s=framenames("st-bolder", 8,10),
    w=framenames("st-bolder", 11,13)
}
function def_bolder(orient)
    local ovlname = "st-bolder"..orient.."o"
    local animname = "st-bolder"..orient.."a"
    local names = {}
    for i=1,3 do
        def_overlay(ovlname..i, {bolder_base, bolder_arrows[orient][i]})
        names[i] = ovlname..i
    end
    def_anim(animname, buildframes(names, 120), 1)
    def_shmodel("st-bolder-"..orient, animname, "sh-solid")
end
def_bolder("n")
def_bolder("e")
def_bolder("s")
def_bolder("w")


-- Invisible stone --
def_image("st-invisible", {filename="invisible"})


-------------
-- Effects --
-------------
progress(100)

ring_anim_frames = buildframes(framenames("ring-anim", 1,8), 50)
def_anim_images("ring-anim", ring_anim_frames, {xoff=-16,yoff=-16})
