3 * convert intermediate cave format to internal cave structure for
4 * use in logic(). initializes entire internal structure.
10 static const short map[CAVE_TILE_MAX] =
20 [Croundwall_1] = Xroundwall_1,
21 [Croundwall_2] = Xroundwall_2,
22 [Croundwall_3] = Xroundwall_3,
23 [Croundwall_4] = Xroundwall_4,
24 [Csteel_1] = Xsteel_1,
25 [Csteel_2] = Xsteel_2,
26 [Csteel_3] = Xsteel_3,
27 [Csteel_4] = Xsteel_4,
28 [Candroid] = Xandroid,
29 [Ceater_n] = Xeater_n,
30 [Ceater_e] = Xeater_e,
31 [Ceater_s] = Xeater_s,
32 [Ceater_w] = Xeater_w,
34 [Cbug_1_n] = Xbug_1_n,
35 [Cbug_1_e] = Xbug_1_e,
36 [Cbug_1_s] = Xbug_1_s,
37 [Cbug_1_w] = Xbug_1_w,
38 [Cbug_2_n] = Xbug_2_n,
39 [Cbug_2_e] = Xbug_2_e,
40 [Cbug_2_s] = Xbug_2_s,
41 [Cbug_2_w] = Xbug_2_w,
42 [Ctank_1_n] = Xtank_1_n,
43 [Ctank_1_e] = Xtank_1_e,
44 [Ctank_1_s] = Xtank_1_s,
45 [Ctank_1_w] = Xtank_1_w,
46 [Ctank_2_n] = Xtank_2_n,
47 [Ctank_2_e] = Xtank_2_e,
48 [Ctank_2_s] = Xtank_2_s,
49 [Ctank_2_w] = Xtank_2_w,
50 [Cemerald] = Xemerald,
51 [Cdiamond] = Xdiamond,
56 [Cspring_e] = Xspring_e,
57 [Cspring_w] = Xspring_w,
58 [Cpush_emerald_e] = Xpush_emerald_e,
59 [Cpush_emerald_w] = Xpush_emerald_w,
60 [Cpush_diamond_e] = Xpush_diamond_e,
61 [Cpush_diamond_w] = Xpush_diamond_w,
62 [Cpush_stone_e] = Xpush_stone_e,
63 [Cpush_stone_w] = Xpush_stone_w,
64 [Cpush_bomb_e] = Xpush_bomb_e,
65 [Cpush_bomb_w] = Xpush_bomb_w,
66 [Cpush_nut_e] = Xpush_nut_e,
67 [Cpush_nut_w] = Xpush_nut_w,
68 [Cpush_spring_e] = Xpush_spring_e,
69 [Cpush_spring_w] = Xpush_spring_w,
70 [Cdynamite] = Xdynamite,
71 [Cdynamite_1] = Xdynamite_1,
72 [Cdynamite_2] = Xdynamite_2,
73 [Cdynamite_3] = Xdynamite_3,
74 [Cdynamite_4] = Xdynamite_4,
91 [Cfake_door_1] = Xfake_door_1,
92 [Cfake_door_2] = Xfake_door_2,
93 [Cfake_door_3] = Xfake_door_3,
94 [Cfake_door_4] = Xfake_door_4,
95 [Cfake_door_5] = Xfake_door_5,
96 [Cfake_door_6] = Xfake_door_6,
97 [Cfake_door_7] = Xfake_door_7,
98 [Cfake_door_8] = Xfake_door_8,
99 [Cballoon] = Xballoon,
102 [Camoeba_1] = Xamoeba_1,
103 [Camoeba_2] = Xamoeba_2,
104 [Camoeba_3] = Xamoeba_3,
105 [Camoeba_4] = Xamoeba_4,
106 [Camoeba_5] = Xamoeba_5,
107 [Camoeba_6] = Xamoeba_6,
108 [Camoeba_7] = Xamoeba_7,
109 [Camoeba_8] = Xamoeba_8,
111 [Cwonderwall] = Xwonderwall,
115 [Cacid_nw] = Xacid_nw,
116 [Cacid_ne] = Xacid_ne,
117 [Cacid_sw] = Xacid_sw,
119 [Cacid_se] = Xacid_se,
128 [Cfake_acid_1] = Xfake_acid_1,
129 [Cfake_acid_2] = Xfake_acid_2,
130 [Cfake_acid_3] = Xfake_acid_3,
131 [Cfake_acid_4] = Xfake_acid_4,
132 [Cfake_acid_5] = Xfake_acid_5,
133 [Cfake_acid_6] = Xfake_acid_6,
134 [Cfake_acid_7] = Xfake_acid_7,
135 [Cfake_acid_8] = Xfake_acid_8,
136 [Cfake_blank] = Xfake_blank,
137 [Cfake_grass] = Xfake_grass,
138 [Cfake_amoeba] = Xfake_amoeba,
140 [Cmagnify] = Xmagnify,
142 [Csand_stone] = Xsand_stone,
143 [Cslide_ns] = Xslide_ns,
144 [Cslide_ew] = Xslide_ew,
149 [Cwind_any] = Xwind_any,
150 [Cwind_stop] = Xwind_stop,
156 [Cdecor_1] = Xdecor_1,
157 [Cdecor_2] = Xdecor_2,
158 [Cdecor_3] = Xdecor_3,
159 [Cdecor_4] = Xdecor_4,
160 [Cdecor_5] = Xdecor_5,
161 [Cdecor_6] = Xdecor_6,
162 [Cdecor_7] = Xdecor_7,
163 [Cdecor_8] = Xdecor_8,
164 [Cdecor_9] = Xdecor_9,
165 [Cdecor_10] = Xdecor_10,
166 [Cdecor_11] = Xdecor_11,
167 [Cdecor_12] = Xdecor_12,
168 [Calpha_0] = Xalpha_0,
169 [Calpha_1] = Xalpha_1,
170 [Calpha_2] = Xalpha_2,
171 [Calpha_3] = Xalpha_3,
172 [Calpha_4] = Xalpha_4,
173 [Calpha_5] = Xalpha_5,
174 [Calpha_6] = Xalpha_6,
175 [Calpha_7] = Xalpha_7,
176 [Calpha_8] = Xalpha_8,
177 [Calpha_9] = Xalpha_9,
178 [Calpha_excla] = Xalpha_excla,
179 [Calpha_apost] = Xalpha_apost,
180 [Calpha_comma] = Xalpha_comma,
181 [Calpha_minus] = Xalpha_minus,
182 [Calpha_perio] = Xalpha_perio,
183 [Calpha_colon] = Xalpha_colon,
184 [Calpha_quest] = Xalpha_quest,
185 [Calpha_a] = Xalpha_a,
186 [Calpha_b] = Xalpha_b,
187 [Calpha_c] = Xalpha_c,
188 [Calpha_d] = Xalpha_d,
189 [Calpha_e] = Xalpha_e,
190 [Calpha_f] = Xalpha_f,
191 [Calpha_g] = Xalpha_g,
192 [Calpha_h] = Xalpha_h,
193 [Calpha_i] = Xalpha_i,
194 [Calpha_j] = Xalpha_j,
195 [Calpha_k] = Xalpha_k,
196 [Calpha_l] = Xalpha_l,
197 [Calpha_m] = Xalpha_m,
198 [Calpha_n] = Xalpha_n,
199 [Calpha_o] = Xalpha_o,
200 [Calpha_p] = Xalpha_p,
201 [Calpha_q] = Xalpha_q,
202 [Calpha_r] = Xalpha_r,
203 [Calpha_s] = Xalpha_s,
204 [Calpha_t] = Xalpha_t,
205 [Calpha_u] = Xalpha_u,
206 [Calpha_v] = Xalpha_v,
207 [Calpha_w] = Xalpha_w,
208 [Calpha_x] = Xalpha_x,
209 [Calpha_y] = Xalpha_y,
210 [Calpha_z] = Xalpha_z,
211 [Calpha_arrow_e] = Xalpha_arrow_e,
212 [Calpha_arrow_w] = Xalpha_arrow_w,
213 [Calpha_copyr] = Xalpha_copyr
216 int map_em_element_C_to_X(int element_em_cave)
218 if (element_em_cave < 0 || element_em_cave >= CAVE_TILE_MAX)
220 Warn("invalid EM cave element %d", element_em_cave);
225 return map[element_em_cave];
228 int map_em_element_X_to_C(int element_em_game)
230 static unsigned short map_reverse[GAME_TILE_MAX];
231 static boolean map_reverse_initialized = FALSE;
233 if (!map_reverse_initialized)
237 // return "Cblank" for all undefined elements in mapping array
238 for (i = 0; i < GAME_TILE_MAX; i++)
239 map_reverse[i] = Cblank;
241 for (i = 0; i < CAVE_TILE_MAX; i++)
242 map_reverse[map[i]] = i;
244 map_reverse_initialized = TRUE;
247 if (element_em_game < 0 || element_em_game >= GAME_TILE_MAX)
249 Warn("invalid EM game element %d", element_em_game);
254 int element_em_cave = map_reverse[element_em_game];
256 if (element_em_cave == Cblank && element_em_game != Xblank)
257 Warn("unknown EM game element %d", element_em_game);
259 return element_em_cave;
262 void prepare_em_level(void)
268 /* reset all runtime variables to their initial values */
270 game_init_cave_buffers();
272 lev.width = cav.width;
273 lev.height = cav.height;
275 lev.left = CAVE_BUFFER_XOFFSET;
276 lev.top = CAVE_BUFFER_YOFFSET;
277 lev.right = lev.left + lev.width;
278 lev.bottom = lev.top + lev.height;
280 lev.infinite = game_em.use_wrap_around;
281 lev.infinite_true = cav.infinite_true;
285 /* add linked cave buffer columns for wrap-around movement */
286 for (x = 0; x < lev.left; x++)
288 int offset = (lev.infinite_true ? 0 : 1);
290 lev.cavecol[x] = &lev.cavecol[lev.width + x][-offset];
291 lev.nextcol[x] = &lev.nextcol[lev.width + x][-offset];
292 lev.drawcol[x] = &lev.drawcol[lev.width + x][-offset];
293 lev.boomcol[x] = &lev.boomcol[lev.width + x][-offset];
295 lev.cavecol[lev.right + x] = &lev.cavecol[lev.left + x][offset];
296 lev.nextcol[lev.right + x] = &lev.nextcol[lev.left + x][offset];
297 lev.drawcol[lev.right + x] = &lev.drawcol[lev.left + x][offset];
298 lev.boomcol[lev.right + x] = &lev.boomcol[lev.left + x][offset];
302 for (x = 0; x < lev.width; x++)
303 for (y = 0; y < lev.height; y++)
304 lev.cave[lev.left + x][lev.top + y] = map[cav.cave[x][y]];
306 for (x = lev.left; x < lev.right; x++)
307 for (y = lev.top; y < lev.bottom; y++)
308 lev.next[x][y] = lev.draw[x][y] = lev.cave[x][y];
310 lev.time = cav.time_seconds;
311 lev.gems_needed = cav.gems_needed;
314 lev.testmode = cav.testmode;
322 lev.eater_score = cav.eater_score;
323 lev.alien_score = cav.alien_score;
324 lev.bug_score = cav.bug_score;
325 lev.tank_score = cav.tank_score;
326 lev.emerald_score = cav.emerald_score;
327 lev.diamond_score = cav.diamond_score;
328 lev.nut_score = cav.nut_score;
329 lev.slurp_score = cav.slurp_score;
330 lev.dynamite_score = cav.dynamite_score;
331 lev.key_score = cav.key_score;
332 lev.lenses_score = cav.lenses_score;
333 lev.magnify_score = cav.magnify_score;
334 lev.exit_score = cav.exit_score;
336 lev.amoeba_time = cav.amoeba_time;
338 lev.android_move_time = cav.android_move_time;
339 lev.android_move_cnt = cav.android_move_time;
341 lev.android_clone_time = cav.android_clone_time;
342 lev.android_clone_cnt = cav.android_clone_time;
344 lev.ball_time = cav.ball_time;
345 lev.ball_cnt = cav.ball_time;
346 lev.ball_active = cav.ball_active;
347 lev.ball_random = cav.ball_random;
353 lev.lenses_time = cav.lenses_time;
354 lev.lenses_cnt = cav.lenses_active ? cav.lenses_time : 0;
356 lev.magnify_time = cav.magnify_time;
357 lev.magnify_cnt = cav.magnify_active ? cav.magnify_time : 0;
359 lev.wheel_time = cav.wheel_time;
360 lev.wheel_cnt = cav.wheel_active ? cav.wheel_time : 0;
361 lev.wheel_x = cav.wheel_x + lev.left;
362 lev.wheel_y = cav.wheel_y + lev.top;
364 lev.wind_time = cav.wind_time;
365 lev.wind_cnt = cav.wind_time;
366 lev.wind_direction = cav.wind_direction;
368 lev.wonderwall_time = cav.wonderwall_time;
369 lev.wonderwall_active = cav.wonderwall_active;
371 lev.killed_out_of_time = FALSE;
373 lev.num_eater_arrays = cav.num_eater_arrays;
374 lev.num_ball_arrays = cav.num_ball_arrays;
376 for (i = 0; i < 8; i++)
377 for (j = 0; j < 9; j++)
378 lev.eater_array[i][j] = map[cav.eater_array[i][j]];
380 for (i = 0; i < 8; i++)
381 for (j = 0; j < 8; j++)
382 lev.ball_array[i][j] = map[cav.ball_array[i][j]];
384 for (i = 0; i < GAME_TILE_MAX; i++)
385 lev.android_array[i] = map[cav.android_array[i]];
387 lev.home_initial = 0;
389 /* check for players in this level */
390 for (i = 0; i < MAX_PLAYERS; i++)
392 ply[i].exists = FALSE;
393 ply[i].alive = FALSE;
395 if (cav.player_x[i] != -1 &&
396 cav.player_y[i] != -1)
398 ply[i].exists = TRUE;
404 team_mode = getTeamMode_EM();
407 lev.home_initial = 1;
409 lev.home = lev.home_initial;
410 players_left = lev.home_initial;
412 /* assign active players */
413 for (i = 0; i < MAX_PLAYERS; i++)
415 if (ply[i].exists && isActivePlayer_EM(i))
425 /* remove inactive players */
426 for (i = 0; i < MAX_PLAYERS; i++)
428 if (ply[i].exists && !ply[i].alive)
430 int x = cav.player_x[i];
431 int y = cav.player_y[i];
433 lev.cave[lev.left + x][lev.top + y] = Xblank;
434 lev.next[lev.left + x][lev.top + y] = Xblank;
435 lev.draw[lev.left + x][lev.top + y] = Xblank;
439 for (i = 0; i < MAX_PLAYERS; i++)
442 ply[i].anim = PLY_still;
444 ply[i].x = cav.player_x[i] + lev.left;
445 ply[i].y = cav.player_y[i] + lev.top;
446 ply[i].prev_x = ply[i].x;
447 ply[i].prev_y = ply[i].y;
450 ply[i].dynamite_cnt = 0;
453 ply[i].last_move_dir = MV_NONE;
455 ply[i].joy_n = FALSE;
456 ply[i].joy_e = FALSE;
457 ply[i].joy_s = FALSE;
458 ply[i].joy_w = FALSE;
459 ply[i].joy_snap = FALSE;
460 ply[i].joy_drop = FALSE;
461 ply[i].joy_stick = FALSE;
464 // the following engine variables are initialized to version-specific values
465 // in function InitGameEngine() (src/game.c):
467 // - game_em.use_single_button (default: TRUE)
468 // - game_em.use_snap_key_bug (default: FALSE)
469 // - game_em.use_random_bug (default: FALSE)
470 // - game_em.use_old_explosions (default: FALSE)
471 // - game_em.use_old_android (default: FALSE)
472 // - game_em.use_old_push_elements (default: FALSE)
473 // - game_em.use_old_push_into_acid (default: FALSE)
474 // - game_em.use_wrap_around (default: TRUE)
475 // - game_em.use_push_delay (default: TRUE)
477 if (native_em_level.file_version > FILE_VERSION_EM_V5)
478 game_em.use_push_delay = FALSE;
480 game_em.level_solved = FALSE;
481 game_em.game_over = FALSE;
483 game_em.any_player_moving = FALSE;
484 game_em.any_player_snapping = FALSE;
486 game_em.last_moving_player = 0; /* default: first player */
488 for (i = 0; i < MAX_PLAYERS; i++)
489 game_em.last_player_direction[i] = MV_NONE;
491 lev.exit_x = lev.exit_y = -1; /* kludge for playing player exit sound */