54 |
-- 2003-03-08 -- |
-- 2003-03-08 -- |
55 |
-- support for parents that do not accept coordinates, default cell key meanings, updates in default |
-- support for parents that do not accept coordinates, default cell key meanings, updates in default |
56 |
-- parent handling, debug mode |
-- parent handling, debug mode |
57 |
|
-- 2003-03-13 -- several cosmetic changes plus add_multitag, spread_tag, wormholes generator and slope generator |
58 |
|
|
59 |
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
60 |
-- MISCELANEOUS - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
-- MISCELANEOUS - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
805 |
group[key].tag = tag |
group[key].tag = tag |
806 |
end |
end |
807 |
|
|
808 |
|
-- next generic multiple. Multitag can store several cells under one tagnumber |
809 |
|
-- if a function is given, it's result stored. If 'tag' is a function, it's |
810 |
|
-- stored as a first-class type, unexecuted. |
811 |
|
function add_multitag(x0, y0, group, tag, func) |
812 |
|
local tab = {x=x0, y=y0} |
813 |
|
|
814 |
|
if (type(func)=="function") then |
815 |
|
tab.tag = func(x, y) |
816 |
|
end |
817 |
|
|
818 |
|
group[tag] = group[tag] or {} |
819 |
|
group[tag][getn(group[tag])+1] = tab |
820 |
|
end |
821 |
|
|
822 |
-- another generic multiple |
-- another generic multiple |
823 |
-- this stores the result of given function(x,y) to table |
-- this stores the result of given function(x,y) to table |
824 |
function add_multiobject(x, y, func, group) |
function add_multiobject(x, y, func, group) |
825 |
tinsert(group, func(x, y)) |
tinsert(group, func(x, y)) |
826 |
end |
end |
827 |
|
|
828 |
|
|
829 |
|
|
830 |
|
-- couple of functions to mark all cells in given area with |
831 |
|
-- given tagnumber. Used for rendering gradients. Area must |
832 |
|
-- be closed, otherwise stack overflow occurs. |
833 |
|
-- usage: |
834 |
|
-- slopes={} |
835 |
|
-- pivots={} |
836 |
|
-- cells["*"]=cell{{{add_multicell, slopes, 1}}} |
837 |
|
-- cells["&"]=cell{{{add_multicell, pivots, slopes}}} |
838 |
|
-- at the end of levelfile: |
839 |
|
-- spread_tag(pivots) |
840 |
|
-- render_slopes(slopes) |
841 |
|
function spread_tag_depth(x0, y0, tab, tag) |
842 |
|
if tab[getkey(x0, y0)] then return end |
843 |
|
|
844 |
|
add_multicell(x0, y0, tab, tag) |
845 |
|
spread_tag_depth(x0, y0-1, tab, tag) |
846 |
|
spread_tag_depth(x0+1, y0 , tab, tag) |
847 |
|
spread_tag_depth(x0, y0+1, tab, tag) |
848 |
|
spread_tag_depth(x0-1, y0 , tab, tag) |
849 |
|
end |
850 |
|
|
851 |
|
function spread_tag(tab, tag) |
852 |
|
local tag = tag or 2 |
853 |
|
for _,val in tab do |
854 |
|
local x0, y0 = val.x, val.y |
855 |
|
local tab0 = val.tag |
856 |
|
spread_tag_depth(x0, y0, tab0, tag) |
857 |
|
end |
858 |
|
end |
859 |
|
|
860 |
|
|
861 |
|
|
862 |
-- add the rubber band between all objects in group 1 and all objects in group 2 |
-- add the rubber band between all objects in group 1 and all objects in group 2 |
863 |
-- that is, each object from gr1 will be connected with each object from gr2 |
-- that is, each object from gr1 will be connected with each object from gr2 |
864 |
function add_rubber_bands(gr1, gr2, strength, length) |
function add_rubber_bands(gr1, gr2, strength, length) |
1019 |
-- generatorfunc, which is a cell[] function to add the floor or items to each registered cell |
-- generatorfunc, which is a cell[] function to add the floor or items to each registered cell |
1020 |
-- the function goes through all registered cells, observing their neighbors |
-- the function goes through all registered cells, observing their neighbors |
1021 |
-- and adding right puzzle stones to right places |
-- and adding right puzzle stones to right places |
1022 |
function render_puzzles (tab, generatorfunc) |
function render_puzzles(tab, generatorfunc) |
1023 |
for _,val in tab do |
for _,val in tab do |
1024 |
local x,y = val.x, val.y |
local x,y = val.x, val.y |
1025 |
|
|
1032 |
generatorfunc(x,y); |
generatorfunc(x,y); |
1033 |
end |
end |
1034 |
|
|
|
dostring("puz = PUZ_"..up..right..down..left) |
|
1035 |
if (val.tag~=2) then |
if (val.tag~=2) then |
1036 |
puzzle(x, y, puz) |
puzzle(x, y, getglobal("PUZ_"..up..right..down..left)) |
1037 |
|
end |
1038 |
|
end |
1039 |
|
end |
1040 |
|
|
1041 |
|
|
1042 |
|
|
1043 |
|
|
1044 |
|
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
1045 |
|
-- BLACK HOLES GENERATOR - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
1046 |
|
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
1047 |
|
function render_wormholes(holes, targets, whole_attribs, actor_mode) |
1048 |
|
local whole_attribs = whole_attribs or {} |
1049 |
|
local actor_mode = actor_mode or 3 |
1050 |
|
|
1051 |
|
for _,hval in holes do |
1052 |
|
local target = 0 |
1053 |
|
for _,tval in targets do |
1054 |
|
if (tval.tag == hval.tag) then |
1055 |
|
target = tval; |
1056 |
|
break |
1057 |
|
end |
1058 |
|
end |
1059 |
|
|
1060 |
|
if (target ~= 0) then |
1061 |
|
local targetx = get_actor_x(target.x, actor_mode) |
1062 |
|
local targety = get_actor_y(target.y, actor_mode) |
1063 |
|
wormhole(hval.x, hval.y, targetx, targety, whole_attribs) |
1064 |
|
end |
1065 |
|
end |
1066 |
|
end |
1067 |
|
|
1068 |
|
function worm_hole_pair(cellfuncs, whole_cell, tgt_cell, whole_parent, tgt_parent, whole_grp, tgt_grp, tagnumber) |
1069 |
|
cellfuncs[whole_cell] = cell{{whole_parent, {add_multicell, whole_grp, tagnumber}}} |
1070 |
|
cellfuncs[tgt_cell] = cell{{tgt_parent, {add_multicell, tgt_grp, tagnumber}}} |
1071 |
|
end |
1072 |
|
|
1073 |
|
|
1074 |
|
|
1075 |
|
|
1076 |
|
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
1077 |
|
-- SLOPE GENERATOR - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
1078 |
|
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
1079 |
|
-- slope generator can render a frame made up of slopes, so that you don't have to create |
1080 |
|
-- each gradient cell manually. |
1081 |
|
-- it's also possible to create some more complicated shapes, but these don't work always |
1082 |
|
|
1083 |
|
__slopemap = {} |
1084 |
|
__slopemap["x0x11x1x"]=SLOPE_N |
1085 |
|
__slopemap["x1x01x1x"]=SLOPE_W |
1086 |
|
__slopemap["x1x10x1x"]=SLOPE_E |
1087 |
|
__slopemap["x1x11x0x"]=SLOPE_S |
1088 |
|
__slopemap["x1x00x0x"]=SLOPE_S |
1089 |
|
__slopemap["x0x10x0x"]=SLOPE_E |
1090 |
|
__slopemap["x0x01x0x"]=SLOPE_W |
1091 |
|
__slopemap["x0x00x1x"]=SLOPE_N |
1092 |
|
|
1093 |
|
-- soft conditions |
1094 |
|
__slopemap["x11x1xxx"]=SLOPE_SMALL_SW |
1095 |
|
__slopemap["x1x1111x"]=SLOPE_LARGE_NE |
1096 |
|
__slopemap["xxx1x11x"]=SLOPE_SMALL_NE |
1097 |
|
__slopemap["x1111x1x"]=SLOPE_LARGE_SW |
1098 |
|
__slopemap["xxxx1x11"]=SLOPE_SMALL_NW |
1099 |
|
__slopemap["11x11x1x"]=SLOPE_LARGE_SE |
1100 |
|
__slopemap["11x1xxxx"]=SLOPE_SMALL_SE |
1101 |
|
__slopemap["x1x11x11"]=SLOPE_LARGE_NW |
1102 |
|
|
1103 |
|
-- hard conditions -- these don't match always, but help to break ambiguous matches |
1104 |
|
__slopemap["x1101x0x"]=SLOPE_SMALL_SW |
1105 |
|
__slopemap["x101111x"]=SLOPE_LARGE_NE |
1106 |
|
__slopemap["x0x1011x"]=SLOPE_SMALL_NE |
1107 |
|
__slopemap["x111101x"]=SLOPE_LARGE_SW |
1108 |
|
__slopemap["x0x01x11"]=SLOPE_SMALL_NW |
1109 |
|
__slopemap["11x11x10"]=SLOPE_LARGE_SE |
1110 |
|
__slopemap["11x10x0x"]=SLOPE_SMALL_SE |
1111 |
|
__slopemap["01x11x11"]=SLOPE_LARGE_NW |
1112 |
|
|
1113 |
|
--inverses |
1114 |
|
__grad_inverse={} |
1115 |
|
__grad_inverse[SLOPE_S]=SLOPE_N |
1116 |
|
__grad_inverse[SLOPE_N]=SLOPE_S |
1117 |
|
__grad_inverse[SLOPE_E]=SLOPE_W |
1118 |
|
__grad_inverse[SLOPE_W]=SLOPE_E |
1119 |
|
__grad_inverse[SLOPE_LARGE_SE]=SLOPE_SMALL_NW |
1120 |
|
__grad_inverse[SLOPE_LARGE_SW]=SLOPE_SMALL_NE |
1121 |
|
__grad_inverse[SLOPE_LARGE_NE]=SLOPE_SMALL_SW |
1122 |
|
__grad_inverse[SLOPE_LARGE_NW]=SLOPE_SMALL_SE |
1123 |
|
__grad_inverse[SLOPE_SMALL_SE]=SLOPE_LARGE_NW |
1124 |
|
__grad_inverse[SLOPE_SMALL_NE]=SLOPE_LARGE_SW |
1125 |
|
__grad_inverse[SLOPE_SMALL_SW]=SLOPE_LARGE_NE |
1126 |
|
__grad_inverse[SLOPE_SMALL_NW]=SLOPE_LARGE_SE |
1127 |
|
|
1128 |
|
-- return correct gradient type based on neighbors |
1129 |
|
function map_slope(x, y, node) |
1130 |
|
local map = __slopemap; |
1131 |
|
local re = ""..node[1]..node[2]..node[3]..node[4]..node[5]..node[6]..node[7]..node[8] |
1132 |
|
-- |
1133 |
|
local longest=0; |
1134 |
|
local longkey=0; |
1135 |
|
local longval=0; |
1136 |
|
local warns={} |
1137 |
|
-- |
1138 |
|
for key,val in map do |
1139 |
|
local okay = 1 |
1140 |
|
local count = 0 |
1141 |
|
-- okay turns to 0, if any char, that is not 'x', doesn't match |
1142 |
|
for i=1,strlen(key) do |
1143 |
|
local char1 = strsub(key, i, i) |
1144 |
|
local char2 = strsub(re, i, i) |
1145 |
|
-- |
1146 |
|
if ((char1~='x')and(char2~='x')and(char1~=char2)) then |
1147 |
|
okay = 0 |
1148 |
|
break |
1149 |
|
else |
1150 |
|
if ((char1~='x')and(char2~='x')) then |
1151 |
|
count = count +1 |
1152 |
|
end |
1153 |
|
end |
1154 |
|
end |
1155 |
|
-- |
1156 |
|
if (okay==1) then |
1157 |
|
if (count>longest) then |
1158 |
|
longest = count; |
1159 |
|
longkey = key; |
1160 |
|
longval = val; |
1161 |
|
warns = {} |
1162 |
|
elseif (count==longest) then |
1163 |
|
tinsert(warns, "ambiguous match: '"..longkey.."' vs. '"..key.."' for re '"..re.."'") |
1164 |
|
end |
1165 |
|
end |
1166 |
|
end |
1167 |
|
-- |
1168 |
|
for i=1,getn(warns) do |
1169 |
|
debug(warns[i]) |
1170 |
|
end |
1171 |
|
|
1172 |
|
if (longest==0) then |
1173 |
|
warning("render_slopes: no match for mask '"..re.."' at ["..x..","..y.."].") |
1174 |
|
end |
1175 |
|
|
1176 |
|
return longval; |
1177 |
|
end |
1178 |
|
|
1179 |
|
function render_slopes(tab, invert) |
1180 |
|
for _,val in tab do |
1181 |
|
local x,y = val.x, val.y |
1182 |
|
|
1183 |
|
local node = {} |
1184 |
|
tinsert(node, (tab[getkey(x-1,y-1)] ~= nil) or 0) |
1185 |
|
tinsert(node, (tab[getkey(x ,y-1)] ~= nil) or 0) |
1186 |
|
tinsert(node, (tab[getkey(x+1,y-1)] ~= nil) or 0) |
1187 |
|
tinsert(node, (tab[getkey(x-1,y )] ~= nil) or 0) |
1188 |
|
tinsert(node, (tab[getkey(x+1,y )] ~= nil) or 0) |
1189 |
|
tinsert(node, (tab[getkey(x-1,y+1)] ~= nil) or 0) |
1190 |
|
tinsert(node, (tab[getkey(x ,y+1)] ~= nil) or 0) |
1191 |
|
tinsert(node, (tab[getkey(x+1,y+1)] ~= nil) or 0) |
1192 |
|
|
1193 |
|
if (val.tag~=2) then |
1194 |
|
if (not (invert)) then |
1195 |
|
gradient(x, y, map_slope(x, y, node)) |
1196 |
|
else |
1197 |
|
gradient(x, y, __grad_inverse[map_slope(x, y, node)]) |
1198 |
|
end |
1199 |
end |
end |
1200 |
end |
end |
1201 |
end |
end |
1265 |
|
|
1266 |
-- common constructions |
-- common constructions |
1267 |
map_cell_meaning("W", cell{stone="st-wood"}) |
map_cell_meaning("W", cell{stone="st-wood"}) |
1268 |
|
map_cell_meaning("B", cell{stone="st-block"}) |
1269 |
|
map_cell_meaning("D", cell{stone="st-death"}) |
1270 |
map_cell_meaning("=", cell{stone="st-glass"}) |
map_cell_meaning("=", cell{stone="st-glass"}) |
1271 |
map_cell_meaning("X", cell{stone="st-grate1"}) |
map_cell_meaning("X", cell{stone="st-grate1"}) |
1272 |
map_cell_meaning("~", cell{stone="st-timer"}) |
map_cell_meaning("~", cell{stone="st-timer"}) |
1273 |
|
|
1274 |
|
-- actors |
1275 |
map_cell_meaning("o", cell{actor={"ac-whiteball-small", {player=0, mouseforce=1}}}) |
map_cell_meaning("o", cell{actor={"ac-whiteball-small", {player=0, mouseforce=1}}}) |
1276 |
map_cell_meaning("O", cell{actor={"ac-blackball", {player=0, mouseforce=1}}}) |
map_cell_meaning("O", cell{actor={"ac-blackball", {player=0, mouseforce=1}}}) |
1277 |
|
|
1280 |
map_cell_meaning("O", hollow) |
map_cell_meaning("O", hollow) |
1281 |
end |
end |
1282 |
|
|
1283 |
|
function multiplayer_mode() |
1284 |
|
map_cell_meaning("1", cell{item="it-yinyang", actor={"ac-blackball", {player=0, mouseforce=1}}}) |
1285 |
|
map_cell_meaning("2", cell{item="it-yinyang", actor={"ac-whiteball", {player=1, mouseforce=1}}}) |
1286 |
|
end |
1287 |
|
|
1288 |
function grass_mode() |
function grass_mode() |
1289 |
map_cell_meaning(" ", cell{floor="fl-leaves"}) |
map_cell_meaning(" ", cell{floor="fl-leaves"}) |
1290 |
map_cell_meaning("#", cell{stone="st-rock1"}) |
map_cell_meaning("#", cell{stone="st-rock1"}) |