home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GameStar Special 2004 August
/
GSSH0804.iso
/
Geschicklichkeit
/
Enigma
/
Enigma-081.exe
/
data
/
levels
/
ralf04.lua
< prev
next >
Wrap
Text File
|
2003-05-20
|
16KB
|
610 lines
-- A level for Enigma
-- Name: Enigris
-- Filename: ralf04.lua
-- Copyright: (C) Mar 2003 Ralf Westram
-- Contact: amgine@reallysoft.de
-- License: GPL v2.0 or above
--warning_raises_error = 1
dofile(enigma.FindDataFile("levels/ralf.lua"))
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
floorface = "fl-marble"
areafloorface = "fl-sahara"
prevfloorface = "fl-bluegray"
uncountedface = "st-brick"
countedface = "st-glass"
wallface = "st-glass"
floorcell = cell{floor={face=floorface}}
areafloorcell = cell{floor={face=areafloorface}}
prevfloorcell = cell{floor={face=prevfloorface}}
marble = cell{actor={face="ac-blackball", attr={player=0}, mode=3}}
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
level = {
"O!!!!!!!!!!!O.......",
"%!!!!!!!!!!!%.@@@@@.",
"%!!!!!!!!!!!%.@@@@@.",
"%!!!!!!!!!!!%.@@@@@.",
"%!!!!!!!!!!!%.@@@@@.",
"%!!!!!!!!!!!%.@@@@@.",
"%!!!!!!!!!!!%...T...",
"%!!!!!!!!!!!%.#####.",
"%!!!!!!!!!!!%.#1 2#.",
"%!!!!!!!!!!!%.# o #.",
"%!!!!!!!!!!!%.#3 4#.",
"%!!!!!!!!!!!%.##5##.",
"L!!!!!!!!!!!L..###..",
}
cells={}
cells["."] = abyss
cells["o"] = marble
cells["@"] = prevfloorcell
cells["!"] = areafloorcell
cells["%"] = cell{parent=areafloorcell,stone={face=uncountedface}}
cells["L"] = cell{parent=areafloorcell,stone={face="st-laser",attr={on=TRUE, dir=enigma.NORTH,name="soundstone"}}}
cells["O"] = cell{parent={areafloorcell,oxyd}}
cells[" "] = floorcell
cells["#"] = cell{parent=floorcell,stone={face=wallface}}
cells["T"] = cell{parent=floorcell,stone={face="st-timer",attr={action="callback", target="tick",interval=0.1}}}
cells["1"] = cell{parent=floorcell,item={face="it-trigger",attr={action="callback", target="trigger1"}}}
cells["2"] = cell{parent=floorcell,item={face="it-trigger",attr={action="callback", target="trigger2"}}}
cells["3"] = cell{parent=floorcell,item={face="it-trigger",attr={action="callback", target="trigger3"}}}
cells["4"] = cell{parent=floorcell,item={face="it-trigger",attr={action="callback", target="trigger4"}}}
cells["5"] = cell{parent=floorcell,item={face="it-trigger",attr={action="callback", target="trigger5"}}}
triggers = 5
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- The drop field:
dfieldx,dfieldy = 1,0
dfieldw,dfieldh = 11,13
-- The preview field:
pfieldx,pfieldy = 14,0
pfieldw,pfieldh = 5,5
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- The stones:
stone1={
"xx",
"x ",
"x ",
}
stone2={
"x ",
"x ",
"xx",
}
stone3={
"x",
"x",
"x",
"x",
}
stone4={
"x ",
"xx",
" x",
}
stone5={
" x",
"xx",
"x ",
}
stone6={
" x ",
"xxx",
}
stone7={
"xx",
"xx",
}
--stone8={
-- " x ",
-- "xxx",
-- " x ",
--}
--stone9={
-- " x",
-- "xxx",
-- "x ",
--}
--stone10={
-- "x ",
-- "xxx",
-- " x",
--}
--stone10={
-- "x ",
-- "xxxx",
-- "x ",
--}
stonedef = {
stone1, stone2, stone3, stone4, stone5,
stone6, stone7,
-- stone8, stone9, stone10
} -- list all stones here
stoneface = { -- define different faces for the stones
"st-brownie",
"st-rock5",
"st-glass",
"st-bluegray",
"st-wood_001",
"st-rock2",
"st-stone_break",
"st-fakeoxyd",
-- "st-wood",
-- "st-brick",
-- "st-grate1",
-- "st-grate2",
}
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
randomseed(enigma.GetTicks())
realstonenum = getn(stonedef) -- number of real different stones
stonefacenum = getn(stoneface)
stonexsize = {} -- calculated below
stoneysize = {} -- calculated below
-- precalculate sizes of stones
for s=1,realstonenum do
stonexsize[s],stoneysize[s] = get_map_size(stonedef[s])
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function sound(sound)
enigma.PlaySound(enigma.GetNamedObject("soundstone"), sound)
end
function gen_map(width,height)
local map={}
for h=1,height do
map[h] = strrep(" ",width)
end
return map
end
function plot_stone(smap,x,y)
local row = smap[y]
local nrow = strsub(row,1,x-1).."x"..strsub(row,x+1)
smap[y] = nrow
end
-- generate rotated stones:
stonenum = realstonenum*4 -- including rotated stones
for s=realstonenum+1,stonenum do
local left = s-realstonenum -- index of same stone (rotated leftwards)
stonexsize[s],stoneysize[s] = stoneysize[left],stonexsize[left]
stonedef[s] = gen_map(stonexsize[s],stoneysize[s])
for y=1,stoneysize[left] do
local row = stonedef[left][y]
for x=1,stonexsize[left] do
if (strsub(row,x,x) == "x") then
plot_stone(stonedef[s],stonexsize[s]-y+1,x)
end
end
end
end
-- plots into a map
-- returns 1 if successfull, 0 otherwise
-- typ == 0 -> empty (always successfull)
-- >= 1 -> number of stoneface
function plot_map(tomap,x,y,typ)
-- print(format("x=%i y=%i typ=%i",x,y,typ))
local row = tomap[y]
if (typ > 0) then
local pos = strsub(row,x,x)
if (pos >= "1") then return 0 end -- error, pos already used
end
local nrow = strsub(row,1,x-1)
if (typ==0) then
nrow = nrow.."-"
else
nrow = nrow..tostring(typ)
end
nrow = nrow..strsub(row,x+1)
tomap[y] = nrow
return 1
end
function dump_map(themap)
for y,str in themap do
print(y,"'",str,"'")
end
end
-- inserts a stone into a map
-- returns 1, if stone has been inserted
function insert_stone(tomap,x0,y0,stonenr,facenr)
local stone = stonedef[stonenr]
-- print(format("x=%i y=%i stone=%i face=%i",x0,y0,stonenr,facenr))
for y=1,stoneysize[stonenr] do
local idx = y+y0-1
if (idx >= 1) then
local srow = stone[y]
-- print(format("y=%i srow='%s'",y,srow))
for x=1,stonexsize[stonenr] do
local c = strsub(srow,x,x)
-- print(format("x=%i y=%i c=%s", x,y,c))
if (c=="x") then
local ok = plot_map(tomap,x+x0-1,idx,facenr)
if (ok == 0) then
-- error occurred -> remove already inserted part
local xe,ye = x,y -- error position
for y=1,ye do
idx = y+y0-1
if (idx >= 1) then
local xm = stonexsize[stonenr]
if (y==ye) then xm = xe-1 end
srow = stone[y]
for x=1,xm do
if (strsub(srow,x,x)=="x") then
plot_map(tomap,x+x0-1,idx,0)
end
end
end
end
return 0
end
end
end
end
end
-- dump_map(tomap)
return 1
end
function remove_stone(frommap,x,y,stonenr)
return insert_stone(frommap,x,y,stonenr,0)
end
function ds(x,y,facenr)
set_stone(stoneface[facenr],x,y)
end
function rs(x,y)
enigma.KillStone(x,y)
end
function skull(x,y)
enigma.KillStone(x,y)
set_stone("st-death",x,y)
sound("shatter");
end
function breakout(x,y)
enigma.KillStone(x,y)
end
function nothing(x,y)
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- display defs for preview and game map
dcells={} -- draw
dcells[" "] = cell{{nothing}}
dcells["-"] = cell{parent={{rs}}}
dcells["S"] = cell{parent={{skull}}}
dcells["X"] = cell{parent={{breakout}}}
for i=1,stonefacenum do
dcells[tostring(i)] = cell{parent={{ds,i}}}
end
pmap = gen_map(pfieldw,pfieldh)
dmap = gen_map(dfieldw,dfieldh)
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
curr_s = {} -- current stone
next_s = {} -- next stone
showx = { 3, 3, 2, 2, 1}
showy = { 3, 3, 2, 2, 1}
broken_lines = {}
normalspeed = 10
points = 0
function show_points()
local p = points
local x1,x2 = 0,(dfieldx+dfieldw)
for y=dfieldh-2,1,-1 do
enigma.KillStone(x1,y)
if (p>0) then
set_stone(countedface,x1,y)
p = p-1
else
set_stone(uncountedface,x1,y)
end
enigma.KillStone(x2,y)
if (p>0) then
set_stone(countedface,x2,y)
p = p-1
else
set_stone(uncountedface,x2,y)
end
end
end
function check_breakouts()
local oldpoints = points
for y,str in dmap do
local spacefound = 0
for x=1,dfieldw do
local c = strsub(str,x,x)
if ((c==" ") or (c=="-")) then
spacefound = spacefound+1
end
end
if (spacefound == 0) then
dmap[y] = strrep("X",dfieldw)
broken_lines[y] = 1
points = points+1
end
end
if (oldpoints ~= points) then
show_points()
if (points ~= 0) then
sound("st-magic");
end
end
end
function fit_broken_lines()
local maxy = 99
for y,broken in broken_lines do
if (broken == 1) then
if (y < maxy) then
maxy = y
end
end
end
if (maxy ~= 99) then
broken_lines[maxy] = 0
for y=maxy-1,1,-1 do
dmap[y+1] = dmap[y]
end
dmap[1] = strrep("-",dfieldw)
else
broken_lines = {}
end
end
function stone_done(init)
if (init==0) then
remove_stone(pmap,next_s.x,next_s.y,next_s.stone)
curr_s = next_s
curr_s.x = random(1,dfieldw-stonexsize[curr_s.stone]+1)
curr_s.y = 2-stoneysize[curr_s.stone]
end
local nr = random(1,stonenum)
next_s = { x=showx[stonexsize[nr]], y=showy[stoneysize[nr]], stone=nr,face=random(1,stonefacenum)}
check_breakouts()
insert_stone(pmap,next_s.x,next_s.y,next_s.stone,next_s.face)
draw_map(pfieldx,pfieldy,pmap,dcells)
end
game_over = 0 -- end of game flag
-- triggerState player on perform
-- trigger? action?
-- 0 NO NO
-- 1 YES YES
-- 2 NO YES
-- 3 YES YES
--
-- triggerState changes by player:
-- 0 -> 1 step onto trigger
-- 1 -> 2 leave trigger (but signal stays valid)
-- 2 -> 1 step again onto trigger before signal was received
-- 3 -> 0 leave trigger after signal has been received
--
-- triggerState changes by tick():
-- 0 -> 0 no trigger -> no action
-- 1 -> 3 player on trigger, mark signal as received
-- 2 -> 0 player already left trigger, nevertheless perform action
-- 3 -> 3 player resting on trigger, perform action as long he rests there
--
-- NOTE: odd trigger means: player is on trigger
-- even trigger means: player is NOT on trigger
triggerState = {}
for x=1,triggers do triggerState[x] = 0 end -- reset triggers
function trigger(which) -- by player
if (triggerState[which]==0) then triggerState[which] = 1
elseif (triggerState[which]==1) then triggerState[which] = 2
elseif (triggerState[which]==2) then triggerState[which] = 1
elseif (triggerState[which]==3) then triggerState[which] = 0
end
end
function readTrigger(which) -- by tick()
local action = 1
if (triggerState[which]==0) then action = 0
elseif (triggerState[which]==1) then triggerState[which] = 3
elseif (triggerState[which]==2) then triggerState[which] = 0
end
return action
end
function trigger1() trigger(1) end -- move left
function trigger2() trigger(2) end -- move right
function trigger3() trigger(3) end -- turn left
function trigger4() trigger(4) end -- turn right
function trigger5() trigger(5) end -- drop/restart
function end_game()
if (game_over == 0) then
game_over = 1
for key,str in dmap do
dmap[key] = gsub(str,"%d","S")
end
end
end
speed = normalspeed
ticker = 0
function game_tick(fall)
if (game_over == 0) then
local stop = 0
if ((curr_s.y + stoneysize[curr_s.stone]-1) >= dfieldh) then
stop = 1
else
remove_stone(dmap,curr_s.x,curr_s.y,curr_s.stone,curr_s.face)
local lastx,lasty,laststone = curr_s.x,curr_s.y,curr_s.stone
local next_sound = ""
-- move/rotate stone
local user_move = 0
if (fall == 1) then
curr_s.y = curr_s.y+1
if (speed == 1) then
next_sound = "pickup"
else
next_sound = "st-move"
end
end
fit_broken_lines()
if (speed ~= 1) then
-- move left
if ((readTrigger(1) == 1) and (curr_s.x > 1)) then
curr_s.x = curr_s.x-1
user_move = 1
next_sound = "st-move"
end
-- move right
if ((readTrigger(2) == 1) and ((curr_s.x + stonexsize[curr_s.stone]) <= dfieldw)) then
curr_s.x = curr_s.x+1
user_move = 1
next_sound = "st-move"
end
local stoneRotated = 0
-- rotate left
if (readTrigger(3) == 1) then
curr_s.stone = curr_s.stone - realstonenum
if (curr_s.stone < 1) then
curr_s.stone = curr_s.stone + stonenum
end
stoneRotated = 1
next_sound = "st-mirrorturn"
end
-- rotate right
if (readTrigger(4) == 1) then
curr_s.stone = curr_s.stone + realstonenum
if (curr_s.stone > stonenum) then
curr_s.stone = curr_s.stone - stonenum
end
stoneRotated = 1
next_sound = "st-mirrorturn"
end
-- correct position if stone was rotated
if (stoneRotated == 1) then
if ((curr_s.x + stonexsize[curr_s.stone] - 1) > dfieldw) then
curr_s.x = dfieldw - (stonexsize[curr_s.stone] - 1)
end
user_move = 1
end
-- drop
if (readTrigger(5) == 1) then
speed = 1
ticker = 0
end
end
local ok = insert_stone(dmap,curr_s.x,curr_s.y,curr_s.stone,curr_s.face)
if ((ok == 0) and (user_move == 1)) then
-- try again with user move skipped
curr_s.x = lastx
curr_s.stone = laststone
ok = insert_stone(dmap,curr_s.x,curr_s.y,curr_s.stone,curr_s.face)
end
if (ok == 0) then -- if error occurred while falling
curr_s.x,curr_s.y = lastx,lasty
insert_stone(dmap,curr_s.x,curr_s.y,curr_s.stone,curr_s.face)
if (curr_s.y <= 1) then -- end of game
end_game()
else
stop = 1
end
else
if (sound ~= "") then
sound(next_sound)
end
end
end
if (stop == 1) then
stone_done(0)
sound("st-thud")
speed = ceil(normalspeed-(points/3))
insert_stone(dmap,curr_s.x,curr_s.y,curr_s.stone,curr_s.face)
end
draw_map(dfieldx,dfieldy,dmap,dcells)
else
if (readTrigger(5) == 1) then -- restart game
game_over = 0
points = 0
show_points()
local line = strrep("-", dfieldw)
for y,str in dmap do
dmap[y] = line
end
stone_done(0)
draw_map(dfieldx,dfieldy,dmap,dcells)
end
end
end
function tick()
ticker = ticker+1
local xmove1 = floor(speed/3)
local xmove2 = floor(speed/3*2)
if (ticker == speed) then
game_tick(1)
ticker = 0
else
if ((ticker == xmove1) or (ticker == xmove2)) then
game_tick(0)
end
end
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
rs_create_world(level,cells,floorcell)
stone_done(1)
stone_done(0)