<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<el:level xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://enigma-game.org/schema/level/1 level.xsd" xmlns:el="http://enigma-game.org/schema/level/1">
  <el:protected >
    <el:info el:type="level">
      <el:identity el:title ="Enignimm" el:subtitle="Yet another Nimm" el:id="20091215ral591"/>
      <el:version el:score="1" el:release="1" el:revision="$Revision: 194 $" el:status="released"/>
      <el:author  el:name="Ronald Lamprecht" el:email="ral@users.berlios.de"/>
      <el:copyright>Copyright © 2009 Ronald Lamprecht</el:copyright>
      <el:license el:type="GPL v2.0 or above" el:open="true"/>
      <el:compatibility el:enigma="1.10"/>
      <el:modes el:easy="false" el:single="true" el:network="false"/>
      <el:comments>
        <el:credits el:showinfo="true" el:showstart="false">Based on Alain's idea of playing "Nimm" on Enigma.</el:credits>
      </el:comments>
      <el:score el:easy="-" el:difficult="3:44"/>
    </el:info>
    <el:luamain><![CDATA[
wo["AutoRespawn"] = true

ti[" "] = {"fl_ivory", friction=5} .. ti{"it_burnable_invisible"}
ti["~"] = {"fl_water"}
ti["#"] = {"st_granite"}
ti["M"] = {"st_brownie"}
ti["."] = {"fl_abyss"} .. ti{"it_seed"}
ti["e"] = {"st_boulder", "lowerboulder#", orientation=EAST} .. ti["~"] .. {"it_strip_e"}
ti[">"] = ti["e"] .. {"it_strip_ew"}
ti["w"] = {"st_boulder", "upperboulder#", orientation=WEST} .. ti["~"] .. {"it_strip_w"}
ti["<"] = ti["w"] .. {"it_strip_ew"}
ti["*"] = {"st_stoneimpulse", "uIS"}
ti["x"] = {"st_stoneimpulse", "bIS"}
ti["R"] = {"st_rotator_ccw"}
ti["k"] = {"it_key", "ukey", code=1}
ti["l"] = {"it_key", "bkey", code=2}
ti["scale"] = {"fl_scales", "scale%%", min=0.9, target="step", _step="%%"}
ti["doorH"] = {"st_door_d", "doorH%%", faces = "ns"}
ti["doorV"] = {"st_door_d", "doorV%%", faces = "ew"}
ti["@"] = {"#ac_marble"} .. ti{"st_lightglass_hollow", "marblehome"}
ti["p"] = {"st_portal_horse"}
ti["!"] = {"#ac_horse", "horse", target="horsecb", steady=false, strength=4, owner=YANG} .. ti["p"] .. {"it_trigger", invisible=true, target="horsehome"}
ti["h"] = {"st_portal_horse", "portu"}
ti["H"] = {"st_portal_horse", "portb"}
ti["|"] = {"st_door_d", "final#", faces = "ew"}
ti["K"] = {"st_key", target="@final#*", code=1}
ti["L"] = {"st_key", target="@final#*", code=2}
ti["o"] = {"st_oxyd"}

resolver = res.autotile(ti, {"0", "9", "scale"}, {"A", "D", "doorV"},
        {"a", "d", "doorH"})

wo(resolver, " ", {
    "################*###",
    "#kM<<<<<<<<<<<<w3###",
    "#.............    R#",
    "##############h# R##",
    "#o  |          #2B1#",
    "####K          #b#a#",
    "#9D5    @  !    4A0#",
    "#d#c#          L####",
    "#8C6#          |  o#",
    "#R# Hp##############",
    "R   ...............#",
    "#7e>>>>>>>>>>>>>>Ml#",
    "#x##################"})

wo:add(YIN, {"it_magicwand"})
wo:add(YANG, {"it_magicwand"})
wo:add({"ot_timer", "uTimer", state=OFF, interval=1.9, loop=false, target="uppertime"})
wo:add({"ot_timer", "bTimer", state=OFF, interval=1.9, loop=false, target="bottomtime"})

uState = 0
uBoulders = no["upperboulder#*"]:sort("linear", E)
uBasepos = po(uBoulders[1])
uCount = #uBoulders
uPendingDraw = false

bState = 0
bBoulders = no["lowerboulder#*"]:sort("linear", W)
bBasepos = po(bBoulders[1])
bCount = #bBoulders
bPendingDraw = false

horse = no["horse"]
horse["_home"] = #horse
hsel = 0
hcount = 0
hstate = 0

function step(value, sender)
    if value == false and sender._step ~= "%4" and sender._step ~= "%8" then return end
    -- upper riddle
    if sender._step == "%1" then  -- big brother's draw
        no["doorV%1"]:close()
        if uCount ~= 0 then
            local sel = cond(uCount == 1, 1, (uCount + 3)%4)
            if sel == 0 then
                sel = random(3)
            end
            hsel = sel
            no["uTimer"]["_numpulses"] = sel - 1
        else
            hsel = 0
            no["doorH%1"]:open()
        end
        horse["destination"] = #no["portu"]
        hstate = 1
        uState = 1
    elseif sender._step == "%2" then
        no["doorH%1"]:close()
        no["uIS"]:signal(1)
        no["uTimer"]:on()
        uState = 2
    elseif sender._step == "%3" then
        no["doorV%2"]:close()
        uState = 3
    elseif sender._step == "%4" then
        if uState == 3 then
            no["doorH%2"]:toggle()
        elseif uState == 1 then
            no["doorH%1"]:open()
        end
        uPendingDraw = true
    elseif sender._step == "%5" then
        if uState == 3 then
            local sel = 0
            for i = 1, #uBoulders do
                if uBoulders[i]:exists() and
                        po(uBoulders[i]) ~= uBasepos + {i-1, 0} then
                    uBoulders[i]["orientation"] = EAST
                    sel = sel + 1
                end
            end
            if sel > 0 then
                no["doorH%2"]:close()
                uCount = uCount - sel
                no["uTimer"]["_numpulses"] = sel - 1
                no["uIS"]:signal(1)
                no["uTimer"]:on()
            end
        elseif uState == 0 then
            no["doorV%1"]:open()
        end
        uState = 5

    -- bottom riddle
    elseif sender._step == "%6" then
        no["doorV%4"]:close()
        if bPendingDraw and bState == 10 then
            no["bIS"]:signal(1)
            no["bTimer"]:on()
        elseif bState == 0 then
            no["doorH%3"]:open()
        end
        bState = 6
    elseif sender._step == "%7" then
        if bCount > 0 then
            no["doorH%3"]:close()
        end
        bState = 7
    elseif sender._step == "%8" then
        if bState == 7 and bCount > 0 then
            no["doorV%3"]:toggle()
        end
    elseif sender._step == "%9" then
        local sel = 0
        for i = 1, #bBoulders do
            if bBoulders[i]:exists() and
                    po(bBoulders[i]) ~= bBasepos + {1-i, 0} then
                bBoulders[i]["orientation"] = WEST
                sel = sel + 1
            end
        end
        if sel > 0 then
            no["doorV%3"]:close()
            bCount = bCount - sel
            no["bTimer"]["_numpulses"] = sel - 1
            no["bIS"]:signal(1)
            no["bTimer"]:on()
        end
        bState = 9
    elseif sender._step == "%10" then  -- big brother's draw
        no["doorH%4"]:close()
        if bCount ~= 0 then
            local sel = cond(bCount == 1, 1, (bCount + 3)%4)
            if sel == 0 then
                sel = random(3)
            end
            hsel = sel
            no["bTimer"]["_numpulses"] = sel - 1
            bPendingDraw = true
        else
            hsel = 0
            no["doorV%4"]:open()
        end
        horse["destination"] = #no["portb"]
        hstate = -1
        bState = 10
    end
end

function horsecb(value, sender)
    if hstate == 1 then
        horse["destination"] = horse["destination"] + N
        hstate = cond(hsel == 0, 8, 2)
        hcount = 1
    elseif hstate == 2 then
        horse["destination"] = #uBoulders[uCount] + cond(hcount == 3, S + E, S)
        hstate = 3
    elseif hstate == 3 then
        horse["_dest"] = horse["destination"]
        horse["destination"] = #uBoulders[uCount]
        uCount = uCount - 1
        hstate = cond(hcount == hsel, 6, 4)
        hcount = hcount + 1
    elseif hstate == 4 then
        horse["destination"] = horse["_dest"]
        hstate = cond(hcount == 3, 5, 2)
    elseif hstate == 5 then
        horse["destination"] = horse["_dest"] + E
        hstate = 2
    elseif hstate == 6 then
        horse["destination"] = #no["portu"] + N
        hstate = 7
    elseif hstate == 7 then
        horse["destination"] = horse["_home"]
        hstate = 0
    elseif hstate == 8 then
        horse["destination"] = #no["ukey"] + S
        horse["_dest"] = horse["destination"]
        hstate = 9
    elseif hstate == 9 then
        horse["destination"] = #no["ukey"]
        hstate = 10
    elseif hstate == 10 then
        horse["destination"] = horse["_dest"]
        wo[no["portu"]] = {"it_magicwand"}
        wo[no["marblehome"]] = {"it_document", text="loss"}
        hstate = 6
    elseif hstate == -1 then
        horse["destination"] = horse["destination"] + S
        hstate = cond(hsel == 0, -8, -2)
        hcount = 1
    elseif hstate == -2 then
        horse["destination"] = #bBoulders[bCount] + cond(hcount == 3, N + W, N)
        hstate = -3
    elseif hstate == -3 then
        horse["_dest"] = horse["destination"]
        horse["destination"] = #bBoulders[bCount]
        bCount = bCount - 1
        hstate = cond(hcount == hsel, -6, -4)
        hcount = hcount + 1
    elseif hstate == -4 then
        horse["destination"] = horse["_dest"]
        hstate = cond(hcount == 3, -5, -2)
    elseif hstate == -5 then
        horse["destination"] = horse["_dest"] + W
        hstate = -2
    elseif hstate == -6 then
        horse["destination"] = #no["portb"] + S
        hstate = -7
    elseif hstate == -7 then
        horse["destination"] = horse["_home"]
        hstate = 0
    elseif hstate == -8 then
        horse["destination"] = #no["bkey"] + N
        horse["_dest"] = horse["destination"]
        hstate = -9
    elseif hstate == -9 then
        horse["destination"] = #no["bkey"]
        hstate = -10
    elseif hstate == -10 then
        horse["destination"] = horse["_dest"]
        wo[no["portb"]+E] = {"it_magicwand"}
        wo[no["marblehome"]] = {"it_document", text="loss"}
        hstate = -6
    end
end

function uppertime(value, sender)
    if sender["_numpulses"] == 0 then
        if uState == 5 then
            no["doorV%1"]:open()
        else
            no["doorV%2"]:open()
        end
    elseif st(no["scale%4"]):exists() then
        sender["_numpulses"] = sender["_numpulses"] - 1
        no["uIS"]:signal(1)
        sender:on()
    else
        sender:on()  -- wait another cycle
    end
end

function bottomtime(value, sender)
    if sender["_numpulses"] == 0 then
        if bState == 6 then
            no["doorH%3"]:open()
        else
            no["doorH%4"]:open()
        end
    elseif st(no["scale%8"]):exists() then
        sender["_numpulses"] = sender["_numpulses"] - 1
        no["bIS"]:signal(1)
        sender:on()
    else
        sender:on()  -- wait another cycle
    end
end

function horsehome(value, sender)
    if value == true and bState == 10 then
         no["doorV%4"]:open()
    end
end
 ]]></el:luamain>
    <el:i18n>
      <el:string el:key="loss">
        <el:english el:translate="true">Doomed ... Shift-F3!!!</el:english>
        <el:translation el:lang="fr">Perdu ... Shift-F3!!!</el:translation>
        <el:translation el:lang="de">Verloren ... Shift-F3!!!</el:translation>
      </el:string>
    </el:i18n>
  </el:protected>
</el:level>
